5
5
/// The models used to represent Dart code.
6
6
library dartdoc.element_type;
7
7
8
+ import 'dart:collection' ;
9
+
8
10
import 'package:analyzer/dart/element/element.dart' ;
9
11
import 'package:analyzer/dart/element/type.dart' ;
10
12
import 'package:dartdoc/src/model.dart' ;
13
+ import 'package:dartdoc/src/model_utils.dart' ;
11
14
12
15
/// Base class representing a type in Dartdoc. It wraps a [DartType] , and
13
16
/// may link to a [ModelElement] .
14
17
abstract class ElementType extends Privacy {
15
18
final DartType _type;
16
19
final PackageGraph packageGraph;
17
- final DefinedElementType returnedFrom;
20
+ final ElementType returnedFrom;
21
+ final Library library;
18
22
19
- ElementType (this ._type, this .packageGraph, this .returnedFrom);
23
+ ElementType (this ._type, this .library, this . packageGraph, this .returnedFrom);
20
24
21
- factory ElementType .from (DartType f, PackageGraph packageGraph,
25
+ factory ElementType .from (
26
+ DartType f, Library library, PackageGraph packageGraph,
22
27
[ElementType returnedFrom]) {
23
28
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);
25
33
} else {
26
34
ModelElement element = ModelElement .fromElement (f.element, packageGraph);
27
35
assert (f is ParameterizedType || f is TypeParameterType );
@@ -32,29 +40,32 @@ abstract class ElementType extends Privacy {
32
40
if (isGenericTypeAlias) {
33
41
assert (element is ! ModelFunctionAnonymous );
34
42
return CallableGenericTypeAliasElementType (
35
- f, packageGraph, element, returnedFrom);
43
+ f, library, packageGraph, element, returnedFrom);
36
44
} else {
37
45
if (element is ModelFunctionAnonymous ) {
38
46
return CallableAnonymousElementType (
39
- f, packageGraph, element, returnedFrom);
47
+ f, library, packageGraph, element, returnedFrom);
40
48
} else {
41
49
assert (element is ! ModelFunctionAnonymous );
42
- return CallableElementType (f, packageGraph, element, returnedFrom);
50
+ return CallableElementType (
51
+ f, library, packageGraph, element, returnedFrom);
43
52
}
44
53
}
45
54
} else if (isGenericTypeAlias) {
46
55
assert (f is TypeParameterType );
47
56
assert (element is ! ModelFunctionAnonymous );
48
57
return GenericTypeAliasElementType (
49
- f, packageGraph, element, returnedFrom);
58
+ f, library, packageGraph, element, returnedFrom);
50
59
}
51
60
if (f is TypeParameterType ) {
52
61
assert (element is ! ModelFunctionAnonymous );
53
- return TypeParameterElementType (f, packageGraph, element, returnedFrom);
62
+ return TypeParameterElementType (
63
+ f, library, packageGraph, element, returnedFrom);
54
64
}
55
65
assert (f is ParameterizedType );
56
66
assert (element is ! ModelFunctionAnonymous );
57
- return ParameterizedElementType (f, packageGraph, element, returnedFrom);
67
+ return ParameterizedElementType (
68
+ f, library, packageGraph, element, returnedFrom);
58
69
}
59
70
}
60
71
@@ -83,31 +94,104 @@ abstract class ElementType extends Privacy {
83
94
/// An [ElementType] that isn't pinned to an Element (or one that is, but whose
84
95
/// element is irrelevant).
85
96
class 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;
89
102
90
103
@override
91
104
bool get isPublic => true ;
92
105
93
106
@override
107
+ String get nameWithGenerics => name;
94
108
95
109
/// dynamic and void are not allowed to have parameterized types.
110
+ @override
96
111
String get linkedName {
97
112
if (type.isDynamic &&
98
113
returnedFrom != null &&
99
- returnedFrom.element.isAsynchronous) return 'Future' ;
114
+ (returnedFrom is DefinedElementType &&
115
+ (returnedFrom as DefinedElementType ).element.isAsynchronous)) {
116
+ return 'Future' ;
117
+ }
100
118
return name;
101
119
}
102
120
103
121
@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' ;
105
189
}
106
190
107
191
class 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);
111
195
112
196
String _linkedName;
113
197
@override
@@ -154,9 +238,9 @@ class ParameterizedElementType extends DefinedElementType {
154
238
}
155
239
156
240
class 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);
160
244
161
245
@override
162
246
String get linkedName => name;
@@ -175,9 +259,9 @@ class TypeParameterElementType extends DefinedElementType {
175
259
abstract class DefinedElementType extends ElementType {
176
260
final ModelElement _element;
177
261
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);
181
265
182
266
ModelElement get element {
183
267
assert (_element != null );
@@ -208,7 +292,7 @@ abstract class DefinedElementType extends ElementType {
208
292
ElementType _returnType;
209
293
ElementType get returnType {
210
294
if (_returnType == null ) {
211
- _returnType = ElementType .from (type, packageGraph, this );
295
+ _returnType = ElementType .from (type, library, packageGraph, this );
212
296
}
213
297
return _returnType;
214
298
}
@@ -221,7 +305,7 @@ abstract class DefinedElementType extends ElementType {
221
305
if (_typeArguments == null ) {
222
306
_typeArguments = (type as ParameterizedType )
223
307
.typeArguments
224
- .map ((f) => ElementType .from (f, packageGraph))
308
+ .map ((f) => ElementType .from (f, library, packageGraph))
225
309
.toList ();
226
310
}
227
311
return _typeArguments;
@@ -238,7 +322,8 @@ abstract class CallableElementTypeMixin implements ParameterizedElementType {
238
322
@override
239
323
ElementType get returnType {
240
324
if (_returnType == null ) {
241
- _returnType = ElementType .from (type.returnType, packageGraph, this );
325
+ _returnType =
326
+ ElementType .from (type.returnType, library, packageGraph, this );
242
327
}
243
328
return _returnType;
244
329
}
@@ -252,19 +337,28 @@ abstract class CallableElementTypeMixin implements ParameterizedElementType {
252
337
Iterable <ElementType > get typeArguments {
253
338
if (_typeArguments == null ) {
254
339
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
+ }
262
346
} 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
+ }
264
358
}
265
359
if (dartTypeArguments != null ) {
266
360
_typeArguments = dartTypeArguments
267
- .map ((f) => ElementType .from (f, packageGraph))
361
+ .map ((f) => ElementType .from (f, library, packageGraph))
268
362
.toList ();
269
363
}
270
364
}
@@ -276,31 +370,31 @@ abstract class CallableElementTypeMixin implements ParameterizedElementType {
276
370
/// function syntax.
277
371
class CallableElementType extends ParameterizedElementType
278
372
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);
282
376
283
377
@override
284
378
String get linkedName {
285
379
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 }' ;
287
381
}
288
382
}
289
383
290
384
/// This is an anonymous function using the generic function syntax (declared
291
385
/// literally with "Function").
292
386
class 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);
296
390
@override
297
391
String get name => 'Function' ;
298
392
299
393
@override
300
394
String get linkedName {
301
395
if (_linkedName == null ) {
302
396
_linkedName =
303
- '${returnType .linkedName } ${super .linkedName }<span class="signature">(${element . linkedParams ()})</span>' ;
397
+ '${returnType .linkedName } ${super .linkedName }<span class="signature">(${linkedParams (element . parameters )})</span>' ;
304
398
}
305
399
return _linkedName;
306
400
}
@@ -312,17 +406,17 @@ abstract class GenericTypeAliasElementTypeMixin {}
312
406
/// A non-callable type backed by a [GenericTypeAliasElement] .
313
407
class GenericTypeAliasElementType extends TypeParameterElementType
314
408
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);
318
412
}
319
413
320
414
/// A Callable generic type alias that may or may not have a name.
321
415
class CallableGenericTypeAliasElementType extends ParameterizedElementType
322
416
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);
326
420
327
421
ModelElement _returnElement;
328
422
@override
@@ -337,8 +431,8 @@ class CallableGenericTypeAliasElementType extends ParameterizedElementType
337
431
@override
338
432
ElementType get returnType {
339
433
if (_returnType == null ) {
340
- _returnType =
341
- ElementType . from ( returnElement.modelType.type, packageGraph, this );
434
+ _returnType = ElementType . from (
435
+ returnElement.modelType.type, library , packageGraph, this );
342
436
}
343
437
return _returnType;
344
438
}
0 commit comments