Skip to content

Commit 8d8a1a0

Browse files
committed
Fix referencing an aliased type parameter. (#3784)
What is an aliased type parameter? Good question! `typedef TD<T> = T;` is such an alias. The fix is pretty simple, we just weren't previously handling this case, or being safe.
1 parent dff86ed commit 8d8a1a0

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

lib/src/element_type.dart

+20-12
Original file line numberDiff line numberDiff line change
@@ -272,20 +272,28 @@ abstract class DefinedElementType extends ElementType {
272272

273273
factory DefinedElementType._from(DartType type, ModelElement modelElement,
274274
Library library, PackageGraph packageGraph) {
275-
// `TypeAliasElement.alias.element` has different implications.
276-
// In that case it is an actual type alias of some kind (generic or
277-
// otherwise). Here however `alias.element` signals that this is a type
278-
// referring to an alias.
279275
if (type is! TypeAliasElement && type.alias != null) {
280-
return AliasedElementType._(
281-
type as ParameterizedType, library, packageGraph, modelElement);
276+
// Here, `alias.element` signals that this is a type referring to an
277+
// alias. (`TypeAliasElement.alias.element` has different implications.
278+
// In that case it is an actual type alias of some kind (generic or
279+
// otherwise).)
280+
return switch (type) {
281+
TypeParameterType() =>
282+
TypeParameterElementType._(type, library, packageGraph, modelElement),
283+
ParameterizedType() =>
284+
AliasedElementType._(type, library, packageGraph, modelElement),
285+
_ => throw UnimplementedError(
286+
'No ElementType implemented for aliased ${type.runtimeType}'),
287+
};
282288
}
283-
if (type is TypeParameterType) {
284-
return TypeParameterElementType._(
285-
type, library, packageGraph, modelElement);
286-
}
287-
return ParameterizedElementType._(
288-
type as ParameterizedType, library, packageGraph, modelElement);
289+
return switch (type) {
290+
TypeParameterType() =>
291+
TypeParameterElementType._(type, library, packageGraph, modelElement),
292+
ParameterizedType() =>
293+
ParameterizedElementType._(type, library, packageGraph, modelElement),
294+
_ => throw UnimplementedError(
295+
'No ElementType implemented for ${type.runtimeType}'),
296+
};
289297
}
290298

291299
@override

test/typedef_test.dart

+15
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,21 @@ typedef T = C;
4040
expect(tTypedef.aliasedType, isA<InterfaceType>());
4141
}
4242

43+
void test_extensionType_generic_referenceToTypeParameter() async {
44+
var library = await bootPackageWithLibrary('''
45+
typedef TD<T> = T;
46+
47+
/// Text [T].
48+
extension type ET<T>(TD<T> _) {}
49+
''');
50+
51+
expect(
52+
library.extensionTypes.named('ET').documentationAsHtml,
53+
// There is no way to link to a type parameter.
54+
contains('<p>Text <code>T</code>.</p>'),
55+
);
56+
}
57+
4358
void test_extensionType_basic() async {
4459
var library = await bootPackageWithLibrary('''
4560
extension type E(int i) {}

0 commit comments

Comments
 (0)