Support the instantiation of abstract constructors
Change-Id: Icc9a06dce056c9ca12bcf5b8c82593c72e9ccd2c
Reviewed-on: https://dart-review.googlesource.com/63480
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
index ef4e517..df44852 100644
--- a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
@@ -1127,13 +1127,6 @@
@override
@failingTest
@potentialAnalyzerProblem
- test_newWithAbstractClass() async {
- return super.test_newWithAbstractClass();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
test_newWithAbstractClass_generic() async {
return super.test_newWithAbstractClass_generic();
}
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 166a2ef..4ee2fda 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -21,6 +21,8 @@
const Code<Message Function(String name)> codeAbstractClassInstantiation =
const Code<Message Function(String name)>(
"AbstractClassInstantiation", templateAbstractClassInstantiation,
+ analyzerCode: "NEW_WITH_ABSTRACT_CLASS",
+ dart2jsCode: "*fatal*",
severity: Severity.errorLegacyWarning);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
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 424cf6e..a5a22ec 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2841,13 +2841,16 @@
} else if (b.isConstructor) {
initialTarget = b.target;
if (type.isAbstract) {
- return new SyntheticExpressionJudgment(evaluateArgumentsBefore(
- arguments,
- buildAbstractClassInstantiationError(
- fasta.templateAbstractClassInstantiation
- .withArguments(type.name),
- type.name,
- nameToken.charOffset)));
+ return new InvalidConstructorInvocationJudgment(
+ evaluateArgumentsBefore(
+ arguments,
+ buildAbstractClassInstantiationError(
+ fasta.templateAbstractClassInstantiation
+ .withArguments(type.name),
+ type.name,
+ nameToken.charOffset)),
+ b.target,
+ arguments);
} else {
target = initialTarget;
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
index 48ec723..24c7be1 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
@@ -86,6 +86,7 @@
IfJudgment,
IllegalAssignmentJudgment,
IndexAssignmentJudgment,
+ InvalidConstructorInvocationJudgment,
InvalidVariableWriteJudgment,
ShadowInvalidInitializer,
LabeledStatementJudgment,
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 f1407bc..a073711 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
@@ -2915,6 +2915,35 @@
}
}
+/// Synthetic judgment class representing an attempt to invoke a constructor
+/// that cannot be invoked.
+class InvalidConstructorInvocationJudgment extends SyntheticExpressionJudgment {
+ final Constructor constructor;
+ final Arguments arguments;
+
+ InvalidConstructorInvocationJudgment(
+ kernel.Expression desugared, this.constructor, this.arguments)
+ : super(desugared);
+
+ @override
+ Expression infer<Expression, Statement, Initializer, Type>(
+ ShadowTypeInferrer inferrer,
+ Factory<Expression, Statement, Initializer, Type> factory,
+ DartType typeContext) {
+ for (var argument in arguments.positional) {
+ inferrer.inferExpression(factory, argument, const UnknownType(), true);
+ }
+ for (var argument in arguments.named) {
+ inferrer.inferExpression(
+ factory, argument.value, const UnknownType(), true);
+ }
+ inferredType = constructor.enclosingClass.rawType;
+ inferrer.listener.constructorInvocation(
+ this, arguments.fileOffset, constructor, inferredType);
+ return super.infer(inferrer, factory, typeContext);
+ }
+}
+
/// Synthetic judgment class representing an attempt to write to a read-only
/// local variable.
class InvalidVariableWriteJudgment extends SyntheticExpressionJudgment {
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index fca60694..2231cab 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -2,7 +2,6 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE.md file.
-AbstractClassInstantiation/analyzerCode: Fail
AbstractClassInstantiation/example: Fail
AbstractClassMember/script5: Fail
AbstractClassMember/script6: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index fd44372..9739d89 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1179,6 +1179,8 @@
AbstractClassInstantiation:
template: "The class '#name' is abstract and can't be instantiated."
severity: ERROR_LEGACY_WARNING
+ analyzerCode: NEW_WITH_ABSTRACT_CLASS
+ dart2jsCode: "*fatal*"
AbstractRedirectedClassInstantiation:
template: "Factory redirects to class '#name', which is abstract and can't be instantiated."