Store resolution for instance creation even when wrong number of arguments.
R=brianwilkerson@google.com, paulberry@google.com
Change-Id: Id9526b2e3bfc731b4a27638b3190795357878811
Reviewed-on: https://dart-review.googlesource.com/65168
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
index 0c770a5..814034c 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
@@ -738,13 +738,6 @@
@override
@failingTest
- test_extraPositionalArguments_const() async {
- // Bad state: No type information for A at 42
- await super.test_extraPositionalArguments_const();
- }
-
- @override
- @failingTest
test_extraPositionalArguments_const_super() async {
// Bad state: No type information for 0 at 65
await super.test_extraPositionalArguments_const_super();
@@ -2090,13 +2083,6 @@
@override
@failingTest
- test_notEnoughRequiredArguments_const() async {
- // Bad state: No type information for A at 47
- await super.test_notEnoughRequiredArguments_const();
- }
-
- @override
- @failingTest
test_optionalParameterInOperator_named() async {
// Expected 1 errors of type CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, found 0
await super.test_optionalParameterInOperator_named();
@@ -2712,13 +2698,6 @@
@override
@failingTest
- test_undefinedNamedParameter() async {
- // Bad state: No type information for A at 42
- await super.test_undefinedNamedParameter();
- }
-
- @override
- @failingTest
test_uriDoesNotExist_export() async {
// Expected 1 errors of type CompileTimeErrorCode.URI_DOES_NOT_EXIST, found 0
await super.test_uriDoesNotExist_export();
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 52429fb..4ff2e26 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -3458,6 +3458,74 @@
}
}
+ test_invalid_instanceCreation_arguments_named() async {
+ addTestFile(r'''
+class C {
+ C();
+}
+var a = 0;
+main() {
+ new C(x: a);
+}
+''');
+ await resolveTestFile();
+ expect(result.errors, isNotEmpty);
+ var classElement = findElement.class_('C');
+
+ var creation = findNode.instanceCreation('new C(x: a)');
+ _assertConstructorInvocation(creation, classElement);
+
+ NamedExpression argument = creation.argumentList.arguments[0];
+ assertElementNull(argument.name.label);
+ var aRef = argument.expression;
+ assertElement(aRef, findElement.topGet('a'));
+ assertType(aRef, 'int');
+ }
+
+ test_invalid_instanceCreation_arguments_required_01() async {
+ addTestFile(r'''
+class C {
+ C();
+}
+var a = 0;
+main() {
+ new C(a);
+}
+''');
+ await resolveTestFile();
+ expect(result.errors, isNotEmpty);
+ var classElement = findElement.class_('C');
+
+ var creation = findNode.instanceCreation('new C(a)');
+ _assertConstructorInvocation(creation, classElement);
+
+ var aRef = creation.argumentList.arguments[0];
+ assertElement(aRef, findElement.topGet('a'));
+ assertType(aRef, 'int');
+ }
+
+ test_invalid_instanceCreation_arguments_required_21() async {
+ addTestFile(r'''
+class C {
+ C(a, b);
+}
+var a = 0;
+main() {
+ new C(a);
+}
+''');
+ await resolveTestFile();
+ expect(result.errors, isNotEmpty);
+ var classElement = findElement.class_('C');
+
+ var creation = findNode.instanceCreation('new C(a)');
+ _assertConstructorInvocation(creation, classElement);
+
+ var aRef = creation.argumentList.arguments[0];
+ assertElement(aRef, findElement.topGet('a'));
+ assertType(aRef, 'int');
+ }
+
test_invalid_methodInvocation_simpleIdentifier() async {
addTestFile(r'''
int foo = 0;
@@ -8435,6 +8503,27 @@
}
}
+ /// Assert that the given [creation] creates instance of the [classElement].
+ /// Limitations: no import prefix, no type arguments, unnamed constructor.
+ void _assertConstructorInvocation(
+ InstanceCreationExpression creation, ClassElement classElement) {
+ assertType(creation, classElement.name);
+
+ var constructorName = creation.constructorName;
+ var constructorElement = classElement.unnamedConstructor;
+ expect(constructorName.staticElement, constructorElement);
+
+ var typeName = constructorName.type;
+ expect(typeName.typeArguments, isNull);
+
+ SimpleIdentifier typeIdentifier = typeName.name;
+ assertElement(typeIdentifier, classElement);
+ assertType(typeIdentifier, classElement.name);
+
+ // Only unnamed constructors are supported now.
+ expect(constructorName.name, isNull);
+ }
+
void _assertDefaultParameter(
DefaultFormalParameter node, ParameterElement element,
{String name, int offset, ParameterKind kind, DartType type}) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 739aac9..1f5e6b5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2767,13 +2767,20 @@
LocatedMessage argMessage = checkArgumentsForFunction(
target.function, arguments, charOffset, typeParameters);
if (argMessage != null) {
- return new SyntheticExpressionJudgment(throwNoSuchMethodError(
+ var error = throwNoSuchMethodError(
forest.literalNull(null)..fileOffset = charOffset,
target.name.name,
arguments,
charOffset,
candidate: target,
- argMessage: argMessage));
+ argMessage: argMessage);
+ if (target is Constructor) {
+ return new InvalidConstructorInvocationJudgment(
+ error, target, arguments)
+ ..fileOffset = charOffset;
+ } else {
+ return new SyntheticExpressionJudgment(error);
+ }
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index 2b9cc4e..71d3160 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -2864,7 +2864,8 @@
}
/// Synthetic judgment class representing an attempt to invoke an unresolved
-/// constructor, or a constructor that cannot be invoked.
+/// constructor, or a constructor that cannot be invoked, or a resolved
+/// constructor with wrong number of arguments.
class InvalidConstructorInvocationJudgment extends SyntheticExpressionJudgment {
final Constructor constructor;
final Arguments arguments;