NNBD Migrator: Handle super redirecting initializers

Change-Id: I52043caaad81a89fe12cc554c32d1b0943d37b27
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/127420
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
This commit is contained in:
Sam Rawlins 2019-12-05 22:59:50 +00:00 committed by commit-bot@chromium.org
parent baf1afa902
commit 41d8b9ee63
3 changed files with 81 additions and 3 deletions

View file

@ -1204,7 +1204,8 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
}
return type;
} else if (staticElement is FunctionElement ||
staticElement is MethodElement) {
staticElement is MethodElement ||
staticElement is ConstructorElement) {
return getOrComputeElementType(staticElement);
} else if (staticElement is PropertyAccessorElement) {
var elementType = getOrComputeElementType(staticElement);
@ -1261,6 +1262,23 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
return _makeNonNullLiteralType(node);
}
@override
DecoratedType visitSuperConstructorInvocation(
SuperConstructorInvocation node) {
var callee = node.staticElement;
var nullabilityNode = NullabilityNode.forInferredType();
var createdType = DecoratedType(callee.returnType, nullabilityNode);
var calleeType = getOrComputeElementType(callee, targetType: createdType);
_handleInvocationArguments(
node,
node.argumentList.arguments,
null /* typeArguments */,
[] /* typeArgumentTypes */,
calleeType,
[] /* constructorTypeParameters */);
return null;
}
@override
DecoratedType visitSuperExpression(SuperExpression node) {
return _handleThisOrSuper(node);
@ -1933,7 +1951,7 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
}
}
/// Creates the necessary constraint(s) for an [argumentList] when invoking an
/// Creates the necessary constraint(s) for an [ArgumentList] when invoking an
/// executable element whose type is [calleeType].
///
/// Returns the decorated return type of the invocation, after any necessary

View file

@ -220,7 +220,7 @@ class InstantiateToBoundsOrigin extends EdgeOrigin {
/// check.
///
/// Before the migration, there was no way to say `is int?`, and therefore,
// `is int` should migrate to non-null int.
/// `is int` should migrate to non-null int.
class IsCheckMainTypeOrigin extends EdgeOrigin {
IsCheckMainTypeOrigin(Source source, TypeAnnotation node)
: super(source, node);

View file

@ -1665,6 +1665,66 @@ class C {
// exception to be thrown.
}
test_constructor_withRedirectingSuperInitializer() async {
await analyze('''
class C {
C.named(int i);
}
class D extends C {
D(int j) : super.named(j);
}
''');
var namedConstructor = findElement.constructor('named', of: 'C');
var constructorType = variables.decoratedElementType(namedConstructor);
var constructorParameterType = constructorType.positionalParameters[0];
assertEdge(
decoratedTypeAnnotation('int j').node, constructorParameterType.node,
hard: true);
}
@FailingTest(
reason: 'Need to pass type arguments along in '
'EdgeBuilder.visitSuperConstructorInvocation')
test_constructor_withRedirectingSuperInitializer_withTypeArgument() async {
await analyze('''
class C<T> {
C.named(T i);
}
class D extends C<int> {
D(int j) : super.named(j);
}
''');
var namedConstructor = findElement.constructor('named', of: 'C');
var constructorType = variables.decoratedElementType(namedConstructor);
var constructorParameterType = constructorType.positionalParameters[0];
assertEdge(
decoratedTypeAnnotation('int j').node, constructorParameterType.node,
hard: true);
}
@FailingTest(
reason: 'Need to pass type arguments along in '
'EdgeBuilder.visitSuperConstructorInvocation')
test_constructor_withRedirectingSuperInitializer_withTypeVariable() async {
await analyze('''
class C<T> {
C.named(T i);
}
class D<T> extends C<T> {
D(T j) : super.named(j);
}
''');
var namedConstructor = findElement.constructor('named', of: 'C');
var constructorType = variables.decoratedElementType(namedConstructor);
var constructorParameterType = constructorType.positionalParameters[0];
assertEdge(
decoratedTypeAnnotation('int j').node, constructorParameterType.node,
hard: true);
}
test_constructorDeclaration_returnType_generic() async {
await analyze('''
class C<T, U> {