Support constructor invocations with arguments
Change-Id: I2d537121efd29f051d8f533c6f58e0ad10835301
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105964
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/nnbd_migration/lib/src/graph_builder.dart b/pkg/nnbd_migration/lib/src/graph_builder.dart
index 3f88d14..9dc042c 100644
--- a/pkg/nnbd_migration/lib/src/graph_builder.dart
+++ b/pkg/nnbd_migration/lib/src/graph_builder.dart
@@ -288,6 +288,12 @@
}
@override
+ DecoratedType visitFunctionExpressionInvocation(
+ FunctionExpressionInvocation node) {
+ throw UnimplementedError('TODO(brianwilkerson)');
+ }
+
+ @override
DecoratedType visitIfStatement(IfStatement node) {
// TODO(paulberry): should the use of a boolean in an if-statement be
// treated like an implicit `assert(b != null)`? Probably.
@@ -355,11 +361,7 @@
// appropriate type arguments.
throw UnimplementedError('TODO(brianwilkerson)');
}
- if (node.argumentList.arguments.isNotEmpty) {
- // Extract the argument handling from visitMethodInvocation and invoke it
- // here.
- throw UnimplementedError('TODO(brianwilkerson)');
- }
+ _handleInvocationArguments(node.argumentList, calleeType);
return calleeType.returnType;
}
@@ -398,30 +400,11 @@
}
var callee = node.methodName.staticElement;
if (callee == null) {
- throw new UnimplementedError('TODO(paulberry)');
+ throw UnimplementedError('TODO(paulberry)');
}
var calleeType = getOrComputeElementType(callee, targetType: targetType);
// TODO(paulberry): substitute if necessary
- var arguments = node.argumentList.arguments;
- int i = 0;
- var suppliedNamedParameters = Set<String>();
- for (var expression in arguments) {
- if (expression is NamedExpression) {
- var name = expression.name.label.name;
- var parameterType = calleeType.namedParameters[name];
- assert(parameterType != null); // TODO(paulberry)
- _handleAssignment(parameterType, expression.expression);
- suppliedNamedParameters.add(name);
- } else {
- assert(calleeType.positionalParameters.length > i); // TODO(paulberry)
- _handleAssignment(calleeType.positionalParameters[i++], expression);
- }
- }
- // Any parameters not supplied must be optional.
- for (var entry in calleeType.namedParameters.entries) {
- if (suppliedNamedParameters.contains(entry.key)) continue;
- entry.value.node.recordNamedParameterNotSupplied(_guards, _graph);
- }
+ _handleInvocationArguments(node.argumentList, calleeType);
var expressionType = calleeType.returnType;
if (isConditional) {
expressionType = expressionType.withNode(
@@ -621,6 +604,36 @@
return sourceType;
}
+ /// Creates the necessary constraint(s) for an [argumentList] when invoking an
+ /// executable element whose type is [calleeType].
+ void _handleInvocationArguments(
+ ArgumentList argumentList, DecoratedType calleeType) {
+ var arguments = argumentList.arguments;
+ int i = 0;
+ var suppliedNamedParameters = Set<String>();
+ for (var expression in arguments) {
+ if (expression is NamedExpression) {
+ var name = expression.name.label.name;
+ var parameterType = calleeType.namedParameters[name];
+ if (parameterType == null) {
+ throw UnimplementedError('TODO(paulberry)');
+ }
+ _handleAssignment(parameterType, expression.expression);
+ suppliedNamedParameters.add(name);
+ } else {
+ if (calleeType.positionalParameters.length <= i) {
+ throw UnimplementedError('TODO(paulberry)');
+ }
+ _handleAssignment(calleeType.positionalParameters[i++], expression);
+ }
+ }
+ // Any parameters not supplied must be optional.
+ for (var entry in calleeType.namedParameters.entries) {
+ if (suppliedNamedParameters.contains(entry.key)) continue;
+ entry.value.node.recordNamedParameterNotSupplied(_guards, _graph);
+ }
+ }
+
DecoratedType _handlePropertyAccess(
Expression node, Expression target, SimpleIdentifier propertyName) {
DecoratedType targetType;
diff --git a/pkg/nnbd_migration/test/migration_visitor_test.dart b/pkg/nnbd_migration/test/migration_visitor_test.dart
index 19bb04c..7f4a08d 100644
--- a/pkg/nnbd_migration/test/migration_visitor_test.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test.dart
@@ -788,6 +788,21 @@
assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
}
+ test_instanceCreation_parameter() async {
+ await analyze('''
+class C {
+ C(int x);
+}
+void f(int y) {
+ C(y);
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int y').node,
+ decoratedTypeAnnotation('int x').node,
+ hard: true);
+ }
+
test_intLiteral() async {
await analyze('''
int f() {