Skip to content

Commit

Permalink
NNBD Migrator: Fix generic super initializers
Browse files Browse the repository at this point in the history
Change-Id: Icc78a248791881a97f5221ee2b5edf6314266225
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/127542
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
  • Loading branch information
srawlins authored and commit-bot@chromium.org committed Dec 9, 2019
1 parent 9605cca commit 991e55f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 33 deletions.
32 changes: 24 additions & 8 deletions pkg/nnbd_migration/lib/src/edge_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -799,11 +799,11 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
InstanceCreationExpression node) {
var callee = node.staticElement;
var typeParameters = callee.enclosingElement.typeParameters;
List<DartType> typeArgumentTypes;
Iterable<DartType> typeArgumentTypes;
List<DecoratedType> decoratedTypeArguments;
var typeArguments = node.constructorName.type.typeArguments;
if (typeArguments != null) {
typeArgumentTypes = typeArguments.arguments.map((t) => t.type).toList();
typeArgumentTypes = typeArguments.arguments.map((t) => t.type);
decoratedTypeArguments = typeArguments.arguments
.map((t) => _variables.decoratedTypeAnnotation(source, t))
.toList();
Expand Down Expand Up @@ -1267,15 +1267,28 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
SuperConstructorInvocation node) {
var callee = node.staticElement;
var nullabilityNode = NullabilityNode.forInferredType();
var createdType = DecoratedType(callee.returnType, nullabilityNode);
var class_ = node.thisOrAncestorOfType<ClassDeclaration>();
var decoratedSupertype = _decoratedClassHierarchy.getDecoratedSupertype(
class_.declaredElement, callee.enclosingElement);
var typeArguments = decoratedSupertype.typeArguments;
Iterable<DartType> typeArgumentTypes;
if (typeArguments != null) {
typeArgumentTypes = typeArguments.map((t) => t.type);
} else {
typeArgumentTypes = [];
}
var createdType = DecoratedType(callee.returnType, nullabilityNode,
typeArguments: typeArguments);
var calleeType = getOrComputeElementType(callee, targetType: createdType);
var constructorTypeParameters = callee.enclosingElement.typeParameters;

_handleInvocationArguments(
node,
node.argumentList.arguments,
null /* typeArguments */,
[] /* typeArgumentTypes */,
null /*typeArguments*/,
typeArgumentTypes,
calleeType,
[] /* constructorTypeParameters */);
constructorTypeParameters);
return null;
}

Expand Down Expand Up @@ -1954,15 +1967,18 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
/// Creates the necessary constraint(s) for an [ArgumentList] when invoking an
/// executable element whose type is [calleeType].
///
/// Only pass [typeArguments] or [typeArgumentTypes] depending on the use
/// case; only one will be used.
///
/// Returns the decorated return type of the invocation, after any necessary
/// substitutions.
DecoratedType _handleInvocationArguments(
AstNode node,
Iterable<AstNode> arguments,
TypeArgumentList typeArguments,
List<DartType> typeArgumentTypes,
Iterable<DartType> typeArgumentTypes,
DecoratedType calleeType,
List<TypeParameterElement> constructorTypeParameters,
Iterable<TypeParameterElement> constructorTypeParameters,
{DartType invokeType}) {
var typeFormals = constructorTypeParameters ?? calleeType.typeFormals;
if (typeFormals.isNotEmpty) {
Expand Down
42 changes: 17 additions & 25 deletions pkg/nnbd_migration/test/edge_builder_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1665,7 +1665,7 @@ class C {
// exception to be thrown.
}

test_constructor_withRedirectingSuperInitializer() async {
test_constructor_superInitializer() async {
await analyze('''
class C {
C.named(int i);
Expand All @@ -1683,45 +1683,37 @@ class D extends C {
hard: true);
}

@FailingTest(
reason: 'Need to pass type arguments along in '
'EdgeBuilder.visitSuperConstructorInvocation')
test_constructor_withRedirectingSuperInitializer_withTypeArgument() async {
test_constructor_superInitializer_withTypeArgument() async {
await analyze('''
class C<T> {
C.named(T i);
C.named(T/*1*/ i);
}
class D extends C<int> {
D(int j) : super.named(j);
class D extends C<int/*2*/> {
D(int/*3*/ 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,
var nullable_t1 = decoratedTypeAnnotation('T/*1*/').node;
var nullable_int2 = decoratedTypeAnnotation('int/*2*/').node;
var nullable_int3 = decoratedTypeAnnotation('int/*3*/').node;
assertEdge(nullable_int3, substitutionNode(nullable_int2, nullable_t1),
hard: true);
}

@FailingTest(
reason: 'Need to pass type arguments along in '
'EdgeBuilder.visitSuperConstructorInvocation')
test_constructor_withRedirectingSuperInitializer_withTypeVariable() async {
test_constructor_superInitializer_withTypeVariable() async {
await analyze('''
class C<T> {
C.named(T i);
C.named(T/*1*/ i);
}
class D<T> extends C<T> {
D(T j) : super.named(j);
class D<U> extends C<U/*2*/> {
D(U/*3*/ 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,
var nullable_t1 = decoratedTypeAnnotation('T/*1*/').node;
var nullable_u2 = decoratedTypeAnnotation('U/*2*/').node;
var nullable_u3 = decoratedTypeAnnotation('U/*3*/').node;
assertEdge(nullable_u3, substitutionNode(nullable_u2, nullable_t1),
hard: true);
}

Expand Down

0 comments on commit 991e55f

Please sign in to comment.