55/// The models used to represent Dart code.
66library dartdoc.element_type;
77
8+ import 'dart:collection' ;
9+
810import 'package:analyzer/dart/element/element.dart' ;
911import 'package:analyzer/dart/element/type.dart' ;
1012import 'package:dartdoc/src/model.dart' ;
13+ import 'package:dartdoc/src/model_utils.dart' ;
1114
1215/// Base class representing a type in Dartdoc. It wraps a [DartType] , and
1316/// may link to a [ModelElement] .
1417abstract class ElementType extends Privacy {
1518 final DartType _type;
1619 final PackageGraph packageGraph;
17- final DefinedElementType returnedFrom;
20+ final ElementType returnedFrom;
21+ final Library library;
1822
19- ElementType (this ._type, this .packageGraph, this .returnedFrom);
23+ ElementType (this ._type, this .library, this . packageGraph, this .returnedFrom);
2024
21- factory ElementType .from (DartType f, PackageGraph packageGraph,
25+ factory ElementType .from (
26+ DartType f, Library library, PackageGraph packageGraph,
2227 [ElementType returnedFrom]) {
2328 if (f.element == null || f.element.kind == ElementKind .DYNAMIC ) {
24- return UndefinedElementType (f, packageGraph, returnedFrom);
29+ if (f is FunctionType ) {
30+ return FunctionTypeElementType (f, library, packageGraph, returnedFrom);
31+ }
32+ return UndefinedElementType (f, library, packageGraph, returnedFrom);
2533 } else {
2634 ModelElement element = ModelElement .fromElement (f.element, packageGraph);
2735 assert (f is ParameterizedType || f is TypeParameterType );
@@ -32,29 +40,32 @@ abstract class ElementType extends Privacy {
3240 if (isGenericTypeAlias) {
3341 assert (element is ! ModelFunctionAnonymous );
3442 return CallableGenericTypeAliasElementType (
35- f, packageGraph, element, returnedFrom);
43+ f, library, packageGraph, element, returnedFrom);
3644 } else {
3745 if (element is ModelFunctionAnonymous ) {
3846 return CallableAnonymousElementType (
39- f, packageGraph, element, returnedFrom);
47+ f, library, packageGraph, element, returnedFrom);
4048 } else {
4149 assert (element is ! ModelFunctionAnonymous );
42- return CallableElementType (f, packageGraph, element, returnedFrom);
50+ return CallableElementType (
51+ f, library, packageGraph, element, returnedFrom);
4352 }
4453 }
4554 } else if (isGenericTypeAlias) {
4655 assert (f is TypeParameterType );
4756 assert (element is ! ModelFunctionAnonymous );
4857 return GenericTypeAliasElementType (
49- f, packageGraph, element, returnedFrom);
58+ f, library, packageGraph, element, returnedFrom);
5059 }
5160 if (f is TypeParameterType ) {
5261 assert (element is ! ModelFunctionAnonymous );
53- return TypeParameterElementType (f, packageGraph, element, returnedFrom);
62+ return TypeParameterElementType (
63+ f, library, packageGraph, element, returnedFrom);
5464 }
5565 assert (f is ParameterizedType );
5666 assert (element is ! ModelFunctionAnonymous );
57- return ParameterizedElementType (f, packageGraph, element, returnedFrom);
67+ return ParameterizedElementType (
68+ f, library, packageGraph, element, returnedFrom);
5869 }
5970 }
6071
@@ -83,31 +94,104 @@ abstract class ElementType extends Privacy {
8394/// An [ElementType] that isn't pinned to an Element (or one that is, but whose
8495/// element is irrelevant).
8596class UndefinedElementType extends ElementType {
86- UndefinedElementType (
87- DartType f, PackageGraph packageGraph, ElementType returnedFrom)
88- : super (f, packageGraph, returnedFrom);
97+ UndefinedElementType (DartType f, Library library, PackageGraph packageGraph,
98+ ElementType returnedFrom)
99+ : super (f, library, packageGraph, returnedFrom);
100+
101+ String _linkedName;
89102
90103 @override
91104 bool get isPublic => true ;
92105
93106 @override
107+ String get nameWithGenerics => name;
94108
95109 /// dynamic and void are not allowed to have parameterized types.
110+ @override
96111 String get linkedName {
97112 if (type.isDynamic &&
98113 returnedFrom != null &&
99- returnedFrom.element.isAsynchronous) return 'Future' ;
114+ (returnedFrom is DefinedElementType &&
115+ (returnedFrom as DefinedElementType ).element.isAsynchronous)) {
116+ return 'Future' ;
117+ }
100118 return name;
101119 }
102120
103121 @override
104- String get nameWithGenerics => name;
122+ String get name => type.name ?? '' ;
123+ }
124+
125+ /// A FunctionType that does not have an underpinning Element.
126+ class FunctionTypeElementType extends UndefinedElementType {
127+ FunctionTypeElementType (DartType f, Library library,
128+ PackageGraph packageGraph, ElementType returnedFrom)
129+ : super (f, library, packageGraph, returnedFrom);
130+
131+ @override
132+ List <Parameter > get parameters {
133+ List <ParameterElement > params = (type as FunctionType ).parameters;
134+ return UnmodifiableListView <Parameter >(params
135+ .map ((p) => ModelElement .from (p, library, packageGraph) as Parameter )
136+ .toList ());
137+ }
138+
139+ ElementType get returnType => ElementType .from (
140+ (type as FunctionType ).returnType, library, packageGraph, this );
141+
142+ @override
143+ String get linkedName {
144+ if (_linkedName == null ) {
145+ StringBuffer buf = StringBuffer ();
146+ buf.write ('${returnType .linkedName } ' );
147+ buf.write ('${nameWithGenerics }' );
148+ buf.write ('<span class="signature">' );
149+ buf.write ('(${linkedParams (parameters )})' );
150+ buf.write ('</span>' );
151+ _linkedName = buf.toString ();
152+ }
153+ return _linkedName;
154+ }
155+
156+ @override
157+ String createLinkedReturnTypeName () => returnType.linkedName;
158+
159+ String _nameWithGenerics;
160+
161+ @override
162+ String get nameWithGenerics {
163+ if (_nameWithGenerics == null ) {
164+ StringBuffer buf = StringBuffer ();
165+ buf.write (name);
166+ if ((type as FunctionType ).typeFormals.isNotEmpty) {
167+ if (! typeFormals.every ((t) => t.name == 'dynamic' )) {
168+ buf.write ('<<wbr><span class="type-parameter">' );
169+ buf.writeAll (typeFormals.map ((t) => t.name),
170+ '</span>, <span class="type-parameter">' );
171+ buf.write ('</span>>' );
172+ }
173+ }
174+ _nameWithGenerics = buf.toString ();
175+ }
176+ return _nameWithGenerics;
177+ }
178+
179+ List <TypeParameter > get typeFormals {
180+ List <TypeParameterElement > typeFormals = (type as FunctionType ).typeFormals;
181+ return UnmodifiableListView <TypeParameter >(typeFormals
182+ .map (
183+ (p) => ModelElement .from (p, library, packageGraph) as TypeParameter )
184+ .toList ());
185+ }
186+
187+ @override
188+ String get name => 'Function' ;
105189}
106190
107191class ParameterizedElementType extends DefinedElementType {
108- ParameterizedElementType (ParameterizedType type, PackageGraph packageGraph ,
109- ModelElement element, ElementType returnedFrom)
110- : super (type, packageGraph, element, returnedFrom);
192+ ParameterizedElementType (ParameterizedType type, Library library ,
193+ PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
194+ : super (type, library, packageGraph, element, returnedFrom);
111195
112196 String _linkedName;
113197 @override
@@ -154,9 +238,9 @@ class ParameterizedElementType extends DefinedElementType {
154238}
155239
156240class TypeParameterElementType extends DefinedElementType {
157- TypeParameterElementType (TypeParameterType type, PackageGraph packageGraph ,
158- ModelElement element, ElementType returnedFrom)
159- : super (type, packageGraph, element, returnedFrom);
241+ TypeParameterElementType (TypeParameterType type, Library library ,
242+ PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
243+ : super (type, library, packageGraph, element, returnedFrom);
160244
161245 @override
162246 String get linkedName => name;
@@ -175,9 +259,9 @@ class TypeParameterElementType extends DefinedElementType {
175259abstract class DefinedElementType extends ElementType {
176260 final ModelElement _element;
177261
178- DefinedElementType (DartType type, PackageGraph packageGraph, this ._element ,
179- ElementType returnedFrom)
180- : super (type, packageGraph, returnedFrom);
262+ DefinedElementType (DartType type, Library library, PackageGraph packageGraph ,
263+ this ._element, ElementType returnedFrom)
264+ : super (type, library, packageGraph, returnedFrom);
181265
182266 ModelElement get element {
183267 assert (_element != null );
@@ -208,7 +292,7 @@ abstract class DefinedElementType extends ElementType {
208292 ElementType _returnType;
209293 ElementType get returnType {
210294 if (_returnType == null ) {
211- _returnType = ElementType .from (type, packageGraph, this );
295+ _returnType = ElementType .from (type, library, packageGraph, this );
212296 }
213297 return _returnType;
214298 }
@@ -221,7 +305,7 @@ abstract class DefinedElementType extends ElementType {
221305 if (_typeArguments == null ) {
222306 _typeArguments = (type as ParameterizedType )
223307 .typeArguments
224- .map ((f) => ElementType .from (f, packageGraph))
308+ .map ((f) => ElementType .from (f, library, packageGraph))
225309 .toList ();
226310 }
227311 return _typeArguments;
@@ -238,7 +322,8 @@ abstract class CallableElementTypeMixin implements ParameterizedElementType {
238322 @override
239323 ElementType get returnType {
240324 if (_returnType == null ) {
241- _returnType = ElementType .from (type.returnType, packageGraph, this );
325+ _returnType =
326+ ElementType .from (type.returnType, library, packageGraph, this );
242327 }
243328 return _returnType;
244329 }
@@ -252,19 +337,28 @@ abstract class CallableElementTypeMixin implements ParameterizedElementType {
252337 Iterable <ElementType > get typeArguments {
253338 if (_typeArguments == null ) {
254339 Iterable <DartType > dartTypeArguments;
255- if (type.typeFormals.isEmpty &&
256- element is ! ModelFunctionAnonymous &&
257- returnedFrom? .element is ! ModelFunctionAnonymous ) {
258- dartTypeArguments = type.typeArguments;
259- } else if (returnedFrom != null &&
260- returnedFrom.type.element is GenericFunctionTypeElement ) {
261- _typeArguments = returnedFrom.typeArguments;
340+ if (returnedFrom is FunctionTypeElementType ) {
341+ if (type.typeFormals.isEmpty) {
342+ dartTypeArguments = type.typeArguments;
343+ } else {
344+ dartTypeArguments = type.typeFormals.map ((f) => f.type);
345+ }
262346 } else {
263- dartTypeArguments = type.typeFormals.map ((f) => f.type);
347+ DefinedElementType elementType = returnedFrom as DefinedElementType ;
348+ if (type.typeFormals.isEmpty &&
349+ element is ! ModelFunctionAnonymous &&
350+ elementType? .element is ! ModelFunctionAnonymous ) {
351+ dartTypeArguments = type.typeArguments;
352+ } else if (returnedFrom != null &&
353+ returnedFrom.type.element is GenericFunctionTypeElement ) {
354+ _typeArguments = (returnedFrom as DefinedElementType ).typeArguments;
355+ } else {
356+ dartTypeArguments = type.typeFormals.map ((f) => f.type);
357+ }
264358 }
265359 if (dartTypeArguments != null ) {
266360 _typeArguments = dartTypeArguments
267- .map ((f) => ElementType .from (f, packageGraph))
361+ .map ((f) => ElementType .from (f, library, packageGraph))
268362 .toList ();
269363 }
270364 }
@@ -276,31 +370,31 @@ abstract class CallableElementTypeMixin implements ParameterizedElementType {
276370/// function syntax.
277371class CallableElementType extends ParameterizedElementType
278372 with CallableElementTypeMixin {
279- CallableElementType (FunctionType t, PackageGraph packageGraph ,
280- ModelElement element, ElementType returnedFrom)
281- : super (t, packageGraph, element, returnedFrom);
373+ CallableElementType (FunctionType t, Library library ,
374+ PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
375+ : super (t, library, packageGraph, element, returnedFrom);
282376
283377 @override
284378 String get linkedName {
285379 if (name != null && name.isNotEmpty) return super .linkedName;
286- return '${nameWithGenerics }(${element . linkedParams (showNames : false ).trim ()}) → ${returnType .linkedName }' ;
380+ return '${nameWithGenerics }(${linkedParams (element . parameters , showNames : false ).trim ()}) → ${returnType .linkedName }' ;
287381 }
288382}
289383
290384/// This is an anonymous function using the generic function syntax (declared
291385/// literally with "Function").
292386class CallableAnonymousElementType extends CallableElementType {
293- CallableAnonymousElementType (FunctionType t, PackageGraph packageGraph ,
294- ModelElement element, ElementType returnedFrom)
295- : super (t, packageGraph, element, returnedFrom);
387+ CallableAnonymousElementType (FunctionType t, Library library ,
388+ PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
389+ : super (t, library, packageGraph, element, returnedFrom);
296390 @override
297391 String get name => 'Function' ;
298392
299393 @override
300394 String get linkedName {
301395 if (_linkedName == null ) {
302396 _linkedName =
303- '${returnType .linkedName } ${super .linkedName }<span class="signature">(${element . linkedParams ()})</span>' ;
397+ '${returnType .linkedName } ${super .linkedName }<span class="signature">(${linkedParams (element . parameters )})</span>' ;
304398 }
305399 return _linkedName;
306400 }
@@ -312,17 +406,17 @@ abstract class GenericTypeAliasElementTypeMixin {}
312406/// A non-callable type backed by a [GenericTypeAliasElement] .
313407class GenericTypeAliasElementType extends TypeParameterElementType
314408 with GenericTypeAliasElementTypeMixin {
315- GenericTypeAliasElementType (TypeParameterType t, PackageGraph packageGraph ,
316- ModelElement element, ElementType returnedFrom)
317- : super (t, packageGraph, element, returnedFrom);
409+ GenericTypeAliasElementType (TypeParameterType t, Library library ,
410+ PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
411+ : super (t, library, packageGraph, element, returnedFrom);
318412}
319413
320414/// A Callable generic type alias that may or may not have a name.
321415class CallableGenericTypeAliasElementType extends ParameterizedElementType
322416 with CallableElementTypeMixin , GenericTypeAliasElementTypeMixin {
323- CallableGenericTypeAliasElementType (FunctionType t, PackageGraph packageGraph ,
324- ModelElement element, ElementType returnedFrom)
325- : super (t, packageGraph, element, returnedFrom);
417+ CallableGenericTypeAliasElementType (FunctionType t, Library library ,
418+ PackageGraph packageGraph, ModelElement element, ElementType returnedFrom)
419+ : super (t, library, packageGraph, element, returnedFrom);
326420
327421 ModelElement _returnElement;
328422 @override
@@ -337,8 +431,8 @@ class CallableGenericTypeAliasElementType extends ParameterizedElementType
337431 @override
338432 ElementType get returnType {
339433 if (_returnType == null ) {
340- _returnType =
341- ElementType . from ( returnElement.modelType.type, packageGraph, this );
434+ _returnType = ElementType . from (
435+ returnElement.modelType.type, library , packageGraph, this );
342436 }
343437 return _returnType;
344438 }
0 commit comments