Skip to content

Commit

Permalink
Fix referencing an aliased type parameter. (dart-lang#3784)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
srawlins committed Jun 27, 2024
1 parent 2417769 commit 510c210
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 12 deletions.
32 changes: 20 additions & 12 deletions lib/src/element_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -272,20 +272,28 @@ abstract class DefinedElementType extends ElementType {

factory DefinedElementType._from(DartType type, ModelElement modelElement,
Library library, PackageGraph packageGraph) {
// `TypeAliasElement.alias.element` has different implications.
// In that case it is an actual type alias of some kind (generic or
// otherwise). Here however `alias.element` signals that this is a type
// referring to an alias.
if (type is! TypeAliasElement && type.alias != null) {
return AliasedElementType._(
type as ParameterizedType, library, packageGraph, modelElement);
// Here, `alias.element` signals that this is a type referring to an
// alias. (`TypeAliasElement.alias.element` has different implications.
// In that case it is an actual type alias of some kind (generic or
// otherwise).)
return switch (type) {
TypeParameterType() =>
TypeParameterElementType._(type, library, packageGraph, modelElement),
ParameterizedType() =>
AliasedElementType._(type, library, packageGraph, modelElement),
_ => throw UnimplementedError(
'No ElementType implemented for aliased ${type.runtimeType}'),
};
}
if (type is TypeParameterType) {
return TypeParameterElementType._(
type, library, packageGraph, modelElement);
}
return ParameterizedElementType._(
type as ParameterizedType, library, packageGraph, modelElement);
return switch (type) {
TypeParameterType() =>
TypeParameterElementType._(type, library, packageGraph, modelElement),
ParameterizedType() =>
ParameterizedElementType._(type, library, packageGraph, modelElement),
_ => throw UnimplementedError(
'No ElementType implemented for ${type.runtimeType}'),
};
}

@override
Expand Down
15 changes: 15 additions & 0 deletions test/typedef_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ typedef T = C;
expect(tTypedef.aliasedType, isA<InterfaceType>());
}

void test_extensionType_generic_referenceToTypeParameter() async {
var library = await bootPackageWithLibrary('''
typedef TD<T> = T;
/// Text [T].
extension type ET<T>(TD<T> _) {}
''');

expect(
library.extensionTypes.named('ET').documentationAsHtml,
// There is no way to link to a type parameter.
contains('<p>Text <code>T</code>.</p>'),
);
}

void test_extensionType_basic() async {
var library = await bootPackageWithLibrary('''
extension type E(int i) {}
Expand Down

0 comments on commit 510c210

Please sign in to comment.