Skip to content

Commit 2e2b5cf

Browse files
authored
Do not depend on FunctionType being a subclass of ParameterizedType (#2665)
* First try * retire the feature * refactor * finish excising implicit future * cleanup * Fix recursive parameter search (flutter test failure) * this seems to work * DefinedElementType back in visibleTypes * Comments and type cleanup
1 parent e58ae4e commit 2e2b5cf

14 files changed

+538
-369
lines changed

lib/src/element_type.dart

Lines changed: 92 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,15 @@ abstract class ElementType extends Privacy with CommentReferable, Nameable {
2626

2727
factory ElementType.from(
2828
DartType f, Library library, PackageGraph packageGraph,
29-
[ElementType returnedFrom]) {
29+
{ElementType returnedFrom}) {
3030
if (f.element == null ||
3131
f.element.kind == ElementKind.DYNAMIC ||
3232
f.element.kind == ElementKind.NEVER) {
3333
if (f is FunctionType) {
34+
if (f.aliasElement != null) {
35+
return AliasedFunctionTypeElementType(
36+
f, library, packageGraph, returnedFrom);
37+
}
3438
return FunctionTypeElementType(f, library, packageGraph, returnedFrom);
3539
}
3640
return UndefinedElementType(f, library, packageGraph, returnedFrom);
@@ -50,10 +54,13 @@ abstract class ElementType extends Privacy with CommentReferable, Nameable {
5054
var isGenericTypeAlias = f.aliasElement != null && f is! InterfaceType;
5155
if (f is FunctionType) {
5256
assert(f is ParameterizedType);
53-
if (isGenericTypeAlias) {
54-
return CallableGenericTypeAliasElementType(
55-
f, library, packageGraph, element, returnedFrom);
56-
}
57+
// This is an indication we have an extremely out of date analyzer....
58+
assert(
59+
!isGenericTypeAlias, 'should never occur: out of date analyzer?');
60+
// And finally, delete this case and its associated class
61+
// after https://dart-review.googlesource.com/c/sdk/+/201520
62+
// is in all published versions of analyzer this version of dartdoc
63+
// is compatible with.
5764
return CallableElementType(
5865
f, library, packageGraph, element, returnedFrom);
5966
} else if (isGenericTypeAlias) {
@@ -93,11 +100,10 @@ abstract class ElementType extends Privacy with CommentReferable, Nameable {
93100
return '';
94101
}
95102

96-
/// An unmodifiable list of this element type's parameters.
97-
List<Parameter> get parameters;
98-
99103
DartType get instantiatedType;
100104

105+
Iterable<ElementType> get typeArguments;
106+
101107
bool isBoundSupertypeTo(ElementType t);
102108
bool isSubtypeOf(ElementType t);
103109

@@ -117,33 +123,20 @@ class UndefinedElementType extends ElementType {
117123
@override
118124
Element get element => null;
119125

120-
String _linkedName;
121-
122126
@override
123127
bool get isPublic => true;
124128

125129
@override
126130
String get name {
127-
if (isImpliedFuture) return 'Future';
128131
if (type.isVoid) return 'void';
129132
assert({'Never', 'void', 'dynamic'}.contains(type.element.name),
130133
'Unrecognized type for UndefinedElementType: ${type.toString()}');
131134
return type.element.name;
132135
}
133136

134-
/// Returns true if this type is an implied `Future`.
135-
bool get isImpliedFuture => (type.isDynamic &&
136-
returnedFrom != null &&
137-
returnedFrom is DefinedElementType &&
138-
(returnedFrom as DefinedElementType).modelElement.isAsynchronous);
139-
140137
@override
141138
String get nameWithGenerics => '$name$nullabilitySuffix';
142139

143-
@override
144-
String get nullabilitySuffix =>
145-
isImpliedFuture && library.isNullSafety ? '?' : super.nullabilitySuffix;
146-
147140
/// Assume that undefined elements don't have useful bounds.
148141
@override
149142
DartType get instantiatedType => type;
@@ -158,45 +151,22 @@ class UndefinedElementType extends ElementType {
158151
String get linkedName => name;
159152

160153
@override
161-
Map<String, CommentReferable> get referenceChildren => {};
154+
Iterable<ElementType> get typeArguments => [];
162155

163156
@override
164-
Iterable<CommentReferable> get referenceParents => [];
157+
Map<String, CommentReferable> get referenceChildren => {};
165158

166159
@override
167-
// TODO(jcollins-g): remove the need for an empty list here.
168-
List<Parameter> get parameters => [];
160+
Iterable<CommentReferable> get referenceParents => [];
169161
}
170162

171163
/// A FunctionType that does not have an underpinning Element.
172164
class FunctionTypeElementType extends UndefinedElementType
173-
with CallableElementTypeMixin {
174-
FunctionTypeElementType(DartType f, Library library,
165+
with Rendered, Callable {
166+
FunctionTypeElementType(FunctionType f, Library library,
175167
PackageGraph packageGraph, ElementType returnedFrom)
176168
: super(f, library, packageGraph, returnedFrom);
177169

178-
@override
179-
List<Parameter> get parameters => type.parameters
180-
.map((p) => ModelElement.from(p, library, packageGraph) as Parameter)
181-
.toList(growable: false);
182-
183-
@override
184-
ElementType get returnType =>
185-
ElementType.from(type.returnType, library, packageGraph, this);
186-
187-
@override
188-
String get linkedName {
189-
_linkedName ??= _renderer.renderLinkedName(this);
190-
return _linkedName;
191-
}
192-
193-
String _nameWithGenerics;
194-
@override
195-
String get nameWithGenerics {
196-
_nameWithGenerics ??= _renderer.renderNameWithGenerics(this);
197-
return _nameWithGenerics;
198-
}
199-
200170
/// An unmodifiable list of this function element's type parameters.
201171
List<TypeParameter> get typeFormals => type.typeFormals
202172
.map((p) => ModelElement.from(p, library, packageGraph) as TypeParameter)
@@ -205,39 +175,42 @@ class FunctionTypeElementType extends UndefinedElementType
205175
@override
206176
String get name => 'Function';
207177

208-
ElementTypeRenderer<FunctionTypeElementType> get _renderer =>
178+
@override
179+
ElementTypeRenderer get _renderer =>
209180
packageGraph.rendererFactory.functionTypeElementTypeRenderer;
210181
}
211182

212-
class ParameterizedElementType extends DefinedElementType {
183+
class AliasedFunctionTypeElementType extends FunctionTypeElementType
184+
with Aliased {
185+
AliasedFunctionTypeElementType(FunctionType f, Library library,
186+
PackageGraph packageGraph, ElementType returnedFrom)
187+
: super(f, library, packageGraph, returnedFrom) {
188+
assert(type.aliasElement != null);
189+
assert(type.aliasArguments != null);
190+
}
191+
192+
@override
193+
ElementTypeRenderer<AliasedFunctionTypeElementType> get _renderer =>
194+
packageGraph.rendererFactory.aliasedFunctionTypeElementTypeRenderer;
195+
}
196+
197+
class ParameterizedElementType extends DefinedElementType with Rendered {
213198
ParameterizedElementType(ParameterizedType type, Library library,
214199
PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
215200
: super(type, library, packageGraph, element, returnedFrom);
216201

217-
String _linkedName;
218-
@override
219-
String get linkedName {
220-
_linkedName ??= _renderer.renderLinkedName(this);
221-
return _linkedName;
222-
}
223-
224-
String _nameWithGenerics;
225202
@override
226-
String get nameWithGenerics {
227-
_nameWithGenerics ??= _renderer.renderNameWithGenerics(this);
228-
return _nameWithGenerics;
229-
}
230-
231203
ElementTypeRenderer<ParameterizedElementType> get _renderer =>
232204
packageGraph.rendererFactory.parameterizedElementTypeRenderer;
233205
}
234206

235-
class AliasedElementType extends ParameterizedElementType {
236-
AliasedElementType(ParameterizedType type, Library library,
237-
PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
238-
: super(type, library, packageGraph, element, returnedFrom) {
239-
assert(type.aliasElement != null);
240-
}
207+
/// A [ElementType] whose underlying type was referrred to by a type alias.
208+
mixin Aliased implements ElementType {
209+
@override
210+
String get name => type.aliasElement.name;
211+
212+
@override
213+
bool get isTypedef => true;
241214

242215
ModelElement _aliasElement;
243216
ModelElement get aliasElement => _aliasElement ??=
@@ -249,6 +222,26 @@ class AliasedElementType extends ParameterizedElementType {
249222
.map((f) => ElementType.from(f, library, packageGraph))
250223
.toList(growable: false);
251224

225+
Iterable<ElementType> _typeArguments;
226+
@override
227+
Iterable<ElementType> get typeArguments =>
228+
_typeArguments ??= (type as ParameterizedType)
229+
.typeArguments
230+
.map((f) => ElementType.from(f, library, packageGraph))
231+
.toList(growable: false);
232+
}
233+
234+
class AliasedElementType extends ParameterizedElementType with Aliased {
235+
AliasedElementType(ParameterizedType type, Library library,
236+
PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
237+
: super(type, library, packageGraph, element, returnedFrom) {
238+
assert(type.aliasElement != null);
239+
}
240+
241+
/// Parameters, if available, for the underlying typedef.
242+
List<Parameter> get aliasedParameters =>
243+
modelElement.isCallable ? modelElement.parameters : [];
244+
252245
@override
253246
ElementTypeRenderer<AliasedElementType> get _renderer =>
254247
packageGraph.rendererFactory.aliasedElementTypeRenderer;
@@ -304,24 +297,8 @@ abstract class DefinedElementType extends ElementType {
304297
return canonicalClass?.isPublic ?? false;
305298
}
306299

307-
@override
308-
bool get isTypedef =>
309-
modelElement is Typedef || modelElement is ModelFunctionTypedef;
310-
311-
@override
312-
List<Parameter> get parameters =>
313-
modelElement.isCallable ? modelElement.parameters : [];
314-
315-
ModelElement get returnElement => modelElement;
316-
ElementType _returnType;
317-
ElementType get returnType {
318-
_returnType ??= ElementType.from(type, library, packageGraph, this);
319-
return _returnType;
320-
}
321-
322300
Iterable<ElementType> _typeArguments;
323-
324-
/// An unmodifiable list of this element type's parameters.
301+
@override
325302
Iterable<ElementType> get typeArguments =>
326303
_typeArguments ??= (type as ParameterizedType)
327304
.typeArguments
@@ -383,38 +360,46 @@ abstract class DefinedElementType extends ElementType {
383360
modelElement.referenceParents;
384361
}
385362

386-
/// Any callable ElementType will mix-in this class, whether anonymous or not.
387-
mixin CallableElementTypeMixin implements ElementType {
388-
@override
389-
// TODO(jcollins-g): remove after dart-lang/dartdoc#2648 is fixed.
390-
String get linkedName;
391-
392-
ModelElement get returnElement => returnType is DefinedElementType
393-
? (returnType as DefinedElementType).modelElement
394-
: null;
363+
/// Any callable ElementType will mix-in this class, whether anonymous or not,
364+
/// unless it is an alias reference.
365+
mixin Callable implements ElementType {
366+
List<Parameter> get parameters => type.parameters
367+
.map((p) => ModelElement.from(p, library, packageGraph) as Parameter)
368+
.toList(growable: false);
395369

396370
ElementType _returnType;
397371
ElementType get returnType {
398-
_returnType ??=
399-
ElementType.from(type.returnType, library, packageGraph, this);
372+
_returnType ??= ElementType.from(type.returnType, library, packageGraph);
400373
return _returnType;
401374
}
402375

403376
@override
404377
FunctionType get type => _type;
378+
}
405379

406-
Iterable<ElementType> _typeArguments;
407-
Iterable<ElementType> get typeArguments =>
408-
_typeArguments ??= type.aliasArguments
409-
?.map((f) => ElementType.from(f, library, packageGraph))
410-
?.toList() ??
411-
[];
380+
/// This [ElementType] uses an [ElementTypeRenderer] to generate
381+
/// some of its parameters.
382+
mixin Rendered implements ElementType {
383+
String _linkedName;
384+
@override
385+
String get linkedName {
386+
_linkedName ??= _renderer.renderLinkedName(this);
387+
return _linkedName;
388+
}
389+
390+
String _nameWithGenerics;
391+
@override
392+
String get nameWithGenerics {
393+
_nameWithGenerics ??= _renderer.renderNameWithGenerics(this);
394+
return _nameWithGenerics;
395+
}
396+
397+
ElementTypeRenderer<ElementType> get _renderer;
412398
}
413399

414400
/// A callable type that may or may not be backed by a declaration using the generic
415401
/// function syntax.
416-
class CallableElementType extends ParameterizedElementType
417-
with CallableElementTypeMixin {
402+
class CallableElementType extends DefinedElementType with Rendered, Callable {
418403
CallableElementType(FunctionType t, Library library,
419404
PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
420405
: super(t, library, packageGraph, element, returnedFrom);
@@ -428,39 +413,9 @@ class CallableElementType extends ParameterizedElementType
428413
packageGraph.rendererFactory.callableElementTypeRenderer;
429414
}
430415

431-
/// Types backed by a [GenericTypeAliasElement] that may or may not be callable.
432-
abstract class GenericTypeAliasElementTypeMixin {}
433-
434416
/// A non-callable type backed by a [GenericTypeAliasElement].
435-
class GenericTypeAliasElementType extends TypeParameterElementType
436-
with GenericTypeAliasElementTypeMixin {
417+
class GenericTypeAliasElementType extends TypeParameterElementType {
437418
GenericTypeAliasElementType(TypeParameterType t, Library library,
438419
PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
439420
: super(t, library, packageGraph, element, returnedFrom);
440421
}
441-
442-
/// A Callable generic type alias that may or may not have a name.
443-
class CallableGenericTypeAliasElementType extends ParameterizedElementType
444-
with CallableElementTypeMixin, GenericTypeAliasElementTypeMixin {
445-
CallableGenericTypeAliasElementType(FunctionType t, Library library,
446-
PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
447-
: super(t, library, packageGraph, element, returnedFrom);
448-
449-
ModelElement _returnElement;
450-
@override
451-
ModelElement get returnElement {
452-
_returnElement ??= ModelElement.fromElement(
453-
type.aliasElement.enclosingElement, packageGraph);
454-
return _returnElement;
455-
}
456-
457-
@override
458-
ElementType get returnType {
459-
_returnType ??=
460-
ElementType.from(type.returnType, library, packageGraph, this);
461-
return _returnType;
462-
}
463-
464-
@override
465-
DartType get instantiatedType => type;
466-
}

lib/src/generator/templates.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import 'package:path/path.dart' as path show Context;
4141

4242
const _visibleTypes = {
4343
Annotation,
44-
CallableElementTypeMixin,
44+
Callable,
4545
Category,
4646
Class,
4747
Constructor,
@@ -50,6 +50,7 @@ const _visibleTypes = {
5050
Enum,
5151
Extension,
5252
FeatureSet,
53+
FunctionTypeElementType,
5354
LanguageFeature,
5455
Library,
5556
LibraryContainer,

0 commit comments

Comments
 (0)