Skip to content

Commit 18c21ee

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
Migration: add support for generic instance creation.
Change-Id: I46d24159a58b7e889cdfa54a9dbb8a94b6c13410 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107645 Reviewed-by: Dan Rubel <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent f7ddfdf commit 18c21ee

3 files changed

Lines changed: 65 additions & 9 deletions

File tree

‎pkg/nnbd_migration/lib/src/edge_builder.dart‎

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType> {
143143
DartType elementType;
144144
if (element is MethodElement) {
145145
elementType = element.type;
146+
} else if (element is ConstructorElement) {
147+
elementType = element.type;
146148
} else {
147149
throw element.runtimeType; // TODO(paulberry)
148150
}
@@ -472,17 +474,22 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType> {
472474
DecoratedType visitInstanceCreationExpression(
473475
InstanceCreationExpression node) {
474476
var callee = node.staticElement;
475-
var calleeType = getOrComputeElementType(callee);
476477
var typeParameters = callee.enclosingElement.typeParameters;
477-
if (typeParameters.isNotEmpty) {
478-
// If the class has type parameters then we might need to substitute the
479-
// appropriate type arguments.
480-
// TODO(brianwilkerson)
481-
_unimplemented(node, 'Instance creation expression with type arguments');
478+
List<DecoratedType> decoratedTypeArguments;
479+
var typeArguments = node.constructorName.type.typeArguments;
480+
if (typeArguments != null) {
481+
decoratedTypeArguments = typeArguments.arguments
482+
.map((t) => _variables.decoratedTypeAnnotation(_source, t))
483+
.toList();
484+
} else {
485+
decoratedTypeArguments = const [];
482486
}
483-
_handleInvocationArguments(node, node.argumentList.arguments,
484-
node.constructorName.type.typeArguments, calleeType, typeParameters);
485-
return calleeType.returnType;
487+
var createdType = DecoratedType(node.staticType, _graph.never,
488+
typeArguments: decoratedTypeArguments);
489+
var calleeType = getOrComputeElementType(callee, targetType: createdType);
490+
_handleInvocationArguments(node, node.argumentList.arguments, typeArguments,
491+
calleeType, typeParameters);
492+
return createdType;
486493
}
487494

488495
@override

‎pkg/nnbd_migration/test/api_test.dart‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,26 @@ int f(int x) {
878878
await _checkSingleFileChanges(content, expected);
879879
}
880880

881+
test_instance_creation_generic() async {
882+
var content = '''
883+
class C<T> {
884+
C(T t);
885+
}
886+
main() {
887+
C<int> c = C<int>(null);
888+
}
889+
''';
890+
var expected = '''
891+
class C<T> {
892+
C(T t);
893+
}
894+
main() {
895+
C<int?> c = C<int?>(null);
896+
}
897+
''';
898+
await _checkSingleFileChanges(content, expected);
899+
}
900+
881901
test_instanceCreation_noTypeArguments_noParameters() async {
882902
var content = '''
883903
void main() {

‎pkg/nnbd_migration/test/edge_builder_test.dart‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,6 +1147,35 @@ C f(C c) => c..[0];
11471147
assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
11481148
}
11491149

1150+
test_instanceCreation_generic() async {
1151+
await analyze('''
1152+
class C<T> {}
1153+
C<int> f() => C<int>();
1154+
''');
1155+
assertEdge(decoratedTypeAnnotation('int>(').node,
1156+
decoratedTypeAnnotation('int> f').node,
1157+
hard: false);
1158+
}
1159+
1160+
test_instanceCreation_generic_parameter() async {
1161+
await analyze('''
1162+
class C<T> {
1163+
C(T t);
1164+
}
1165+
f(int i) => C<int>(i/*check*/);
1166+
''');
1167+
var nullable_i = decoratedTypeAnnotation('int i').node;
1168+
var nullable_c_t = decoratedTypeAnnotation('C<int>').typeArguments[0].node;
1169+
var nullable_t = decoratedTypeAnnotation('T t').node;
1170+
var check_i = checkExpression('i/*check*/');
1171+
var nullable_c_t_or_nullable_t =
1172+
check_i.edges.single.destinationNode as NullabilityNodeForSubstitution;
1173+
expect(nullable_c_t_or_nullable_t.innerNode, same(nullable_c_t));
1174+
expect(nullable_c_t_or_nullable_t.outerNode, same(nullable_t));
1175+
assertNullCheck(check_i,
1176+
assertEdge(nullable_i, nullable_c_t_or_nullable_t, hard: true));
1177+
}
1178+
11501179
test_instanceCreation_parameter_named_optional() async {
11511180
await analyze('''
11521181
class C {

0 commit comments

Comments
 (0)