mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 14:32:49 +00:00
Migration: fix crashes with extension Foo<T extends ...> on T
Change-Id: I3a8f1be4f52a6a49bb57ab032fef668482f5acf6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151002 Reviewed-by: Mike Fairhurst <mfairhurst@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
parent
6f4bc6a9be
commit
43131b575e
|
@ -236,7 +236,8 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
|
|||
} else {
|
||||
assert(enclosingElement is ExtensionElement);
|
||||
final extensionElement = enclosingElement as ExtensionElement;
|
||||
final extendedType = extensionElement.extendedType;
|
||||
final extendedType =
|
||||
_typeSystem.resolveToBound(extensionElement.extendedType);
|
||||
if (extendedType is InterfaceType) {
|
||||
if (extensionElement.typeParameters.isNotEmpty) {
|
||||
substitution = _decoratedClassHierarchy
|
||||
|
@ -743,6 +744,7 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
|
|||
|
||||
DecoratedType visitExtensionDeclaration(ExtensionDeclaration node) {
|
||||
visitClassOrMixinOrExtensionDeclaration(node);
|
||||
_dispatch(node.typeParameters);
|
||||
_dispatch(node.extendedType);
|
||||
return null;
|
||||
}
|
||||
|
@ -2917,6 +2919,8 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
|
|||
NullabilityNode.forInferredType(
|
||||
target.typeArgument(index++))))
|
||||
.toList());
|
||||
} else if (type is TypeParameterType) {
|
||||
return DecoratedType(type, NullabilityNode.forInferredType(target));
|
||||
} else {
|
||||
_unimplemented(node, 'extension of $type (${type.runtimeType}');
|
||||
}
|
||||
|
|
|
@ -2082,6 +2082,48 @@ void g() => f(null);
|
|||
await _checkSingleFileChanges(content, expected);
|
||||
}
|
||||
|
||||
Future<void> test_extension_on_type_param_implementation() async {
|
||||
var content = '''
|
||||
abstract class C {
|
||||
C _clone();
|
||||
}
|
||||
extension Cloner<T extends C> on T {
|
||||
T clone() => _clone() as T;
|
||||
}
|
||||
''';
|
||||
var expected = '''
|
||||
abstract class C {
|
||||
C _clone();
|
||||
}
|
||||
extension Cloner<T extends C> on T {
|
||||
T clone() => _clone() as T;
|
||||
}
|
||||
''';
|
||||
await _checkSingleFileChanges(content, expected);
|
||||
}
|
||||
|
||||
Future<void> test_extension_on_type_param_usage() async {
|
||||
var content = '''
|
||||
abstract class C {
|
||||
C _clone();
|
||||
}
|
||||
extension Cloner<T extends C> on T {
|
||||
T clone() => throw Exception();
|
||||
}
|
||||
C f(C c) => c.clone();
|
||||
''';
|
||||
var expected = '''
|
||||
abstract class C {
|
||||
C _clone();
|
||||
}
|
||||
extension Cloner<T extends C> on T {
|
||||
T clone() => throw Exception();
|
||||
}
|
||||
C f(C c) => c.clone();
|
||||
''';
|
||||
await _checkSingleFileChanges(content, expected);
|
||||
}
|
||||
|
||||
Future<void> test_field_final_uninitalized_used() async {
|
||||
var content = '''
|
||||
class C {
|
||||
|
|
Loading…
Reference in a new issue