Update formated error for nonexisting constructor
This is an alternative fix for #33452.
This was originally fixed in 8e4d5c0a3842c3801ce9310c6322146505e58469,
but it was pointed out that it doesn't work if there were type arguments.
This should fix the problem in more cases.
Change-Id: I08ed27ecea1a8d471be9675d28b997614248c65e
Reviewed-on: https://dart-review.googlesource.com/68080
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
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 dedcf53..00ccdb9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -444,6 +444,7 @@
beginToken.next, beginToken.offset, Constness.explicitConst);
push(popForValue());
} else {
+ pop(); // Name last identifier
String name = pop();
pop(); // Type arguments (ignored, already reported by parser).
Object expression = pop();
@@ -2774,6 +2775,7 @@
push(type);
push(typeArguments ?? NullValue.TypeArguments);
push(name);
+ push(suffix ?? identifier ?? NullValue.Identifier);
}
@override
@@ -2980,6 +2982,8 @@
void buildConstructorReferenceInvocation(
Token nameToken, int offset, Constness constness) {
Arguments arguments = pop();
+ Identifier nameLastIdentifier = pop(NullValue.Identifier);
+ Token nameLastToken = nameLastIdentifier?.token ?? nameToken;
String name = pop();
List<DartType> typeArguments = pop();
@@ -2988,7 +2992,7 @@
ConstantContext savedConstantContext = pop();
if (type is Generator) {
push(type.invokeConstructor(
- typeArguments, name, arguments, nameToken, constness));
+ typeArguments, name, arguments, nameToken, nameLastToken, constness));
} else {
push(new SyntheticExpressionJudgment(throwNoSuchMethodError(
forest.literalNull(null)..fileOffset = offset,
@@ -3010,6 +3014,7 @@
Expression buildConstructorInvocation(
TypeDeclarationBuilder<TypeBuilder, Object> type,
Token nameToken,
+ Token nameLastToken,
Arguments arguments,
String name,
List<DartType> typeArguments,
@@ -3095,16 +3100,13 @@
errorName = debugName(getNodeName(type), name);
}
errorName ??= name;
- if (nameToken.lexeme == type.name && name.isNotEmpty) {
- nameToken = nameToken.next.next;
- }
return new UnresolvedTargetInvocationJudgment(
throwNoSuchMethodError(
forest.literalNull(null)..fileOffset = charOffset,
errorName,
arguments,
- nameToken.charOffset),
+ nameLastToken.charOffset),
arguments)
..fileOffset = arguments.fileOffset;
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index bcda4a0..dd98021 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -235,8 +235,13 @@
return new UnexpectedQualifiedUseGenerator(helper, name, this, false);
}
- Expression invokeConstructor(List<DartType> typeArguments, String name,
- Arguments arguments, Token nameToken, Constness constness) {
+ Expression invokeConstructor(
+ List<DartType> typeArguments,
+ String name,
+ Arguments arguments,
+ Token nameToken,
+ Token nameLastToken,
+ Constness constness) {
if (typeArguments != null) {
assert(forest.argumentsTypeArguments(arguments).isEmpty);
forest.argumentsSetTypeArguments(arguments, typeArguments);
@@ -545,11 +550,16 @@
}
@override
- Expression invokeConstructor(List<DartType> typeArguments, String name,
- Arguments arguments, Token nameToken, Constness constness) {
+ Expression invokeConstructor(
+ List<DartType> typeArguments,
+ String name,
+ Arguments arguments,
+ Token nameToken,
+ Token nameLastToken,
+ Constness constness) {
return helper.wrapInDeferredCheck(
- suffixGenerator.invokeConstructor(
- typeArguments, name, arguments, nameToken, constness),
+ suffixGenerator.invokeConstructor(typeArguments, name, arguments,
+ nameToken, nameLastToken, constness),
prefixGenerator.prefix,
offsetForToken(suffixGenerator.token));
}
@@ -654,11 +664,23 @@
}
@override
- Expression invokeConstructor(List<DartType> typeArguments, String name,
- Arguments arguments, Token nameToken, Constness constness) {
+ Expression invokeConstructor(
+ List<DartType> typeArguments,
+ String name,
+ Arguments arguments,
+ Token nameToken,
+ Token nameLastToken,
+ Constness constness) {
helper.storeTypeUse(offsetForToken(token), declaration.target);
- return helper.buildConstructorInvocation(declaration, nameToken, arguments,
- name, typeArguments, offsetForToken(nameToken ?? token), constness);
+ return helper.buildConstructorInvocation(
+ declaration,
+ nameToken,
+ nameLastToken,
+ arguments,
+ name,
+ typeArguments,
+ offsetForToken(nameToken ?? token),
+ constness);
}
@override
@@ -812,8 +834,13 @@
}
@override
- Expression invokeConstructor(List<DartType> typeArguments, String name,
- Arguments arguments, Token nameToken, Constness constness) {
+ Expression invokeConstructor(
+ List<DartType> typeArguments,
+ String name,
+ Arguments arguments,
+ Token nameToken,
+ Token nameLastToken,
+ Constness constness) {
helper.storeTypeUse(offsetForToken(token), const InvalidType());
if (typeArguments != null) {
assert(forest.argumentsTypeArguments(arguments).isEmpty);
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
index 3072158..0dacced 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
@@ -140,6 +140,7 @@
Expression buildConstructorInvocation(
TypeDeclarationBuilder<KernelTypeBuilder, DartType> type,
Token nameToken,
+ Token nameLastToken,
Arguments arguments,
String name,
List<DartType> typeArguments,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
index 0cd8f04..2500bb1 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
@@ -1330,8 +1330,15 @@
if (send is IncompletePropertyAccessGenerator) {
generator = new UnresolvedNameGenerator(helper, send.token, name);
} else {
- return helper.buildConstructorInvocation(declaration, send.token,
- arguments, name.name, null, token.charOffset, Constness.implicit);
+ return helper.buildConstructorInvocation(
+ declaration,
+ send.token,
+ send.token,
+ arguments,
+ name.name,
+ null,
+ token.charOffset,
+ Constness.implicit);
}
} else {
Declaration setter;
@@ -1358,8 +1365,8 @@
@override
Expression doInvocation(int offset, Arguments arguments) {
- return helper.buildConstructorInvocation(declaration, token, arguments, "",
- null, token.charOffset, Constness.implicit);
+ return helper.buildConstructorInvocation(declaration, token, token,
+ arguments, "", null, token.charOffset, Constness.implicit);
}
}
@@ -1607,11 +1614,16 @@
Token token, this.prefixGenerator, this.isUnresolved)
: super(helper, token);
- Expression invokeConstructor(List<DartType> typeArguments, String name,
- Arguments arguments, Token nameToken, Constness constness) {
+ Expression invokeConstructor(
+ List<DartType> typeArguments,
+ String name,
+ Arguments arguments,
+ Token nameToken,
+ Token nameStringToken,
+ Constness constness) {
helper.storeTypeUse(offsetForToken(token), const InvalidType());
return super.invokeConstructor(
- typeArguments, name, arguments, nameToken, constness);
+ typeArguments, name, arguments, nameToken, nameStringToken, constness);
}
}
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart b/pkg/front_end/testcases/regress/issue_33452.dart
index faffe5d..bd8c790 100644
--- a/pkg/front_end/testcases/regress/issue_33452.dart
+++ b/pkg/front_end/testcases/regress/issue_33452.dart
@@ -2,9 +2,15 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-class ExistingClass {}
+class ExistingClass {
+ ExistingClass.existingConstructor();
+}
main() {
var x = new ExistingClass.nonExistingConstructor();
+ x = new ExistingClass();
+ x = new ExistingClass<String>();
+ x = new ExistingClass<String>.nonExistingConstructor();
+ x = new ExistingClass<String, String>.nonExistingConstructor();
x = new NonExistingClass();
}
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.direct.expect b/pkg/front_end/testcases/regress/issue_33452.dart.direct.expect
index 3d768b8..edcd349 100644
--- a/pkg/front_end/testcases/regress/issue_33452.dart.direct.expect
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.direct.expect
@@ -3,11 +3,15 @@
import "dart:core" as core;
class ExistingClass extends core::Object {
- synthetic constructor •() → void
+ constructor existingConstructor() → void
: super core::Object::•()
;
}
static method main() → dynamic {
dynamic x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass.nonExistingConstructor, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass, 32, core::List::unmodifiable<dynamic>(<core::Type>[core::String]), const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass.nonExistingConstructor, 32, core::List::unmodifiable<dynamic>(<core::Type>[core::String]), const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass.nonExistingConstructor, 32, core::List::unmodifiable<dynamic>(<core::Type>[core::String, core::String]), const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#NonExistingClass, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_33452.dart.direct.transformed.expect
index 3d768b8..edcd349 100644
--- a/pkg/front_end/testcases/regress/issue_33452.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.direct.transformed.expect
@@ -3,11 +3,15 @@
import "dart:core" as core;
class ExistingClass extends core::Object {
- synthetic constructor •() → void
+ constructor existingConstructor() → void
: super core::Object::•()
;
}
static method main() → dynamic {
dynamic x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass.nonExistingConstructor, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass, 32, core::List::unmodifiable<dynamic>(<core::Type>[core::String]), const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass.nonExistingConstructor, 32, core::List::unmodifiable<dynamic>(<core::Type>[core::String]), const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass.nonExistingConstructor, 32, core::List::unmodifiable<dynamic>(<core::Type>[core::String, core::String]), const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#NonExistingClass, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.outline.expect b/pkg/front_end/testcases/regress/issue_33452.dart.outline.expect
index da89296..6f1e5f7 100644
--- a/pkg/front_end/testcases/regress/issue_33452.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.outline.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
class ExistingClass extends core::Object {
- synthetic constructor •() → void
+ constructor existingConstructor() → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.strong.expect b/pkg/front_end/testcases/regress/issue_33452.dart.strong.expect
index d598469..8b82c2c 100644
--- a/pkg/front_end/testcases/regress/issue_33452.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.strong.expect
@@ -1,10 +1,26 @@
// Errors:
//
-// pkg/front_end/testcases/regress/issue_33452.dart:8:29: Error: Method not found: 'ExistingClass.nonExistingConstructor'.
+// pkg/front_end/testcases/regress/issue_33452.dart:10:29: Error: Method not found: 'ExistingClass.nonExistingConstructor'.
// var x = new ExistingClass.nonExistingConstructor();
// ^^^^^^^^^^^^^^^^^^^^^^
//
-// pkg/front_end/testcases/regress/issue_33452.dart:9:11: Error: Method not found: 'NonExistingClass'.
+// pkg/front_end/testcases/regress/issue_33452.dart:11:11: Error: Method not found: 'ExistingClass'.
+// x = new ExistingClass();
+// ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:12:11: Error: Method not found: 'ExistingClass'.
+// x = new ExistingClass<String>();
+// ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:13:33: Error: Method not found: 'ExistingClass.nonExistingConstructor'.
+// x = new ExistingClass<String>.nonExistingConstructor();
+// ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:14:41: Error: Method not found: 'ExistingClass.nonExistingConstructor'.
+// x = new ExistingClass<String, String>.nonExistingConstructor();
+// ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:15:11: Error: Method not found: 'NonExistingClass'.
// x = new NonExistingClass();
// ^^^^^^^^^^^^^^^^
@@ -13,11 +29,15 @@
import "dart:core" as core;
class ExistingClass extends core::Object {
- synthetic constructor •() → void
+ constructor existingConstructor() → void
: super core::Object::•()
;
}
static method main() → dynamic {
dynamic x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass.nonExistingConstructor, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass, 32, core::List::unmodifiable<dynamic>(<core::Type>[core::String]), const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass.nonExistingConstructor, 32, core::List::unmodifiable<dynamic>(<core::Type>[core::String]), const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass.nonExistingConstructor, 32, core::List::unmodifiable<dynamic>(<core::Type>[core::String, core::String]), const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#NonExistingClass, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_33452.dart.strong.transformed.expect
index d598469..8b82c2c 100644
--- a/pkg/front_end/testcases/regress/issue_33452.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.strong.transformed.expect
@@ -1,10 +1,26 @@
// Errors:
//
-// pkg/front_end/testcases/regress/issue_33452.dart:8:29: Error: Method not found: 'ExistingClass.nonExistingConstructor'.
+// pkg/front_end/testcases/regress/issue_33452.dart:10:29: Error: Method not found: 'ExistingClass.nonExistingConstructor'.
// var x = new ExistingClass.nonExistingConstructor();
// ^^^^^^^^^^^^^^^^^^^^^^
//
-// pkg/front_end/testcases/regress/issue_33452.dart:9:11: Error: Method not found: 'NonExistingClass'.
+// pkg/front_end/testcases/regress/issue_33452.dart:11:11: Error: Method not found: 'ExistingClass'.
+// x = new ExistingClass();
+// ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:12:11: Error: Method not found: 'ExistingClass'.
+// x = new ExistingClass<String>();
+// ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:13:33: Error: Method not found: 'ExistingClass.nonExistingConstructor'.
+// x = new ExistingClass<String>.nonExistingConstructor();
+// ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:14:41: Error: Method not found: 'ExistingClass.nonExistingConstructor'.
+// x = new ExistingClass<String, String>.nonExistingConstructor();
+// ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:15:11: Error: Method not found: 'NonExistingClass'.
// x = new NonExistingClass();
// ^^^^^^^^^^^^^^^^
@@ -13,11 +29,15 @@
import "dart:core" as core;
class ExistingClass extends core::Object {
- synthetic constructor •() → void
+ constructor existingConstructor() → void
: super core::Object::•()
;
}
static method main() → dynamic {
dynamic x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass.nonExistingConstructor, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass, 32, core::List::unmodifiable<dynamic>(<core::Type>[core::String]), const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass.nonExistingConstructor, 32, core::List::unmodifiable<dynamic>(<core::Type>[core::String]), const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#ExistingClass.nonExistingConstructor, 32, core::List::unmodifiable<dynamic>(<core::Type>[core::String, core::String]), const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#NonExistingClass, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}