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;