Store resolution for invalid member references.
Change-Id: I7ce556bc4819a77e082d81bb96e54b9cedc68d78
Reviewed-on: https://dart-review.googlesource.com/65021
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 8884134..df61140 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -243,8 +243,10 @@
CompileTimeErrorCode.RETURN_IN_GENERATOR,
CompileTimeErrorCode.SHARED_DEFERRED_PREFIX,
CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT,
+ CompileTimeErrorCode.SUPER_AS_EXPRESSION,
CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT,
CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
+ CompileTimeErrorCode.THIS_ACCESS_FROM_INITIALIZER,
CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
CompileTimeErrorCode.TYPE_PARAMETER_ON_CONSTRUCTOR,
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index d7c20b3..47051d9 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -2379,6 +2379,9 @@
"directives.",
correction: "Try renaming one of the prefixes.");
+ static const CompileTimeErrorCode SUPER_AS_EXPRESSION =
+ const CompileTimeErrorCode.fromFasta('SUPER_AS_EXPRESSION');
+
/**
* 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
* <i>super.m(a<sub>1</sub>, …, a<sub>n</sub>, x<sub>n+1</sub>:
@@ -2455,6 +2458,9 @@
correction: "Try removing the type parameters '<{0}>', or using"
" 'dynamic' as the type argument here instead of a function.");
+ static const CompileTimeErrorCode THIS_ACCESS_FROM_INITIALIZER =
+ const CompileTimeErrorCode.fromFasta('THIS_ACCESS_FROM_INITIALIZER');
+
/**
* 15.3.1 Typedef: Any self reference, either directly, or recursively via
* another typedef, is a compile time error.
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
index 0dc723a..d5956cf 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
@@ -44,6 +44,13 @@
@override
@failingTest
+ @FastaProblem('https://github.com/dart-lang/sdk/issues/33858')
+ test_invalid_fieldInitializer_this() async {
+ await super.test_invalid_fieldInitializer_this();
+ }
+
+ @override
+ @failingTest
test_local_type_parameter_reference_function_named_parameter_type() {
// Stack overflow
return super
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 17ad6e8..52429fb 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -3332,6 +3332,64 @@
assertType(throwExpression.expression, 'int');
}
+ test_invalid_fieldInitializer_field() async {
+ addTestFile(r'''
+class C {
+ final int a = 0;
+ final int b = a + 1;
+}
+''');
+ await resolveTestFile();
+ expect(result.errors, isNotEmpty);
+
+ var aRef = findNode.simple('a + 1');
+ assertElement(aRef, findElement.getter('a'));
+ assertType(aRef, 'int');
+ }
+
+ test_invalid_fieldInitializer_getter() async {
+ addTestFile(r'''
+class C {
+ int get a => 0;
+ final int b = a + 1;
+}
+''');
+ await resolveTestFile();
+ expect(result.errors, isNotEmpty);
+
+ var aRef = findNode.simple('a + 1');
+ assertElement(aRef, findElement.getter('a'));
+ assertType(aRef, 'int');
+ }
+
+ test_invalid_fieldInitializer_method() async {
+ addTestFile(r'''
+class C {
+ int a() => 0;
+ final int b = a + 1;
+}
+''');
+ await resolveTestFile();
+ expect(result.errors, isNotEmpty);
+
+ var aRef = findNode.simple('a + 1');
+ assertElement(aRef, findElement.method('a'));
+ assertType(aRef, '() → int');
+ }
+
+ test_invalid_fieldInitializer_this() async {
+ addTestFile(r'''
+class C {
+ final b = this;
+}
+''');
+ await resolveTestFile();
+ expect(result.errors, isNotEmpty);
+
+ var thisRef = findNode.this_('this');
+ assertType(thisRef, 'C');
+ }
+
test_invalid_instanceCreation_abstract() async {
addTestFile(r'''
abstract class C<T> {
@@ -8658,6 +8716,14 @@
return _node(search).getAncestor((n) => n is SimpleFormalParameter);
}
+ SuperExpression super_(String search) {
+ return _node(search).getAncestor((n) => n is SuperExpression);
+ }
+
+ ThisExpression this_(String search) {
+ return _node(search).getAncestor((n) => n is ThisExpression);
+ }
+
ThrowExpression throw_(String search) {
return _node(search).getAncestor((n) => n is ThrowExpression);
}
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 03da49d..18b2133 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -6060,6 +6060,8 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageSuperAsExpression = const MessageCode(
"SuperAsExpression",
+ analyzerCode: "SUPER_AS_EXPRESSION",
+ dart2jsCode: "*fatal*",
message: r"""Can't use 'super' as an expression.""",
tip:
r"""To delegate a constructor to a super constructor, put the super call as an initializer.""");
@@ -6291,9 +6293,8 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(String name)> codeThisAccessInFieldInitializer =
const Code<Message Function(String name)>(
- "ThisAccessInFieldInitializer",
- templateThisAccessInFieldInitializer,
-);
+ "ThisAccessInFieldInitializer", templateThisAccessInFieldInitializer,
+ analyzerCode: "THIS_ACCESS_FROM_INITIALIZER", dart2jsCode: "*fatal*");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsThisAccessInFieldInitializer(String name) {
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 4dc25a7..cf2eeb0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1518,7 +1518,7 @@
classBuilder.origin.findStaticBuilder(name, charOffset, uri, library);
}
if (declaration != null && member.isField && declaration.isInstanceMember) {
- return new IncompleteErrorGenerator(this, token,
+ return new IncompleteErrorGenerator(this, token, declaration.target,
fasta.templateThisAccessInFieldInitializer.withArguments(name));
}
if (declaration == null ||
@@ -3087,7 +3087,7 @@
push(new ThisAccessGenerator(this, token, inInitializer));
} else {
push(new IncompleteErrorGenerator(
- this, token, fasta.messageThisAsIdentifier));
+ this, token, null, fasta.messageThisAsIdentifier));
}
}
@@ -3100,7 +3100,7 @@
push(new ThisAccessGenerator(this, token, inInitializer, isSuper: true));
} else {
push(new IncompleteErrorGenerator(
- this, token, fasta.messageSuperAsIdentifier));
+ this, token, null, fasta.messageSuperAsIdentifier));
}
}
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 0341daa..962ceae 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
@@ -92,6 +92,7 @@
IllegalAssignmentJudgment,
IndexAssignmentJudgment,
InvalidConstructorInvocationJudgment,
+ InvalidPropertyGetJudgment,
InvalidVariableWriteJudgment,
ShadowInvalidFieldInitializer,
ShadowInvalidInitializer,
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 6f72d90..0b4dadd 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
@@ -81,6 +81,7 @@
ComplexAssignmentJudgment,
IllegalAssignmentJudgment,
IndexAssignmentJudgment,
+ InvalidPropertyGetJudgment,
InvalidVariableWriteJudgment,
LoadLibraryTearOffJudgment,
MethodInvocationJudgment,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
index ce81823..392ac7d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
@@ -196,10 +196,11 @@
class IncompleteErrorGenerator extends IncompleteSendGenerator
with ErroneousExpressionGenerator {
+ final Member member;
final Message message;
IncompleteErrorGenerator(
- ExpressionGeneratorHelper helper, Token token, this.message)
+ ExpressionGeneratorHelper helper, Token token, this.member, this.message)
: super(helper, token, null);
String get debugName => "IncompleteErrorGenerator";
@@ -219,6 +220,13 @@
doInvocation(int offset, Arguments arguments) => this;
@override
+ Expression buildSimpleRead() {
+ var error = buildError(forest.argumentsEmpty(token), isGetter: true);
+ return new InvalidPropertyGetJudgment(error, member)
+ ..fileOffset = offsetForToken(token);
+ }
+
+ @override
void printOn(StringSink sink) {
sink.write(", message: ");
sink.write(message.code.name);
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 af4f102..2b9cc4e 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
@@ -2923,6 +2923,25 @@
}
}
+/// Synthetic judgment class representing an attempt reference a member
+/// that is not allowed at this location.
+class InvalidPropertyGetJudgment extends SyntheticExpressionJudgment {
+ final Member member;
+
+ InvalidPropertyGetJudgment(kernel.Expression desugared, this.member)
+ : super(desugared);
+
+ @override
+ Expression infer<Expression, Statement, Initializer, Type>(
+ ShadowTypeInferrer inferrer,
+ Factory<Expression, Statement, Initializer, Type> factory,
+ DartType typeContext) {
+ var inferredType = member?.getterType ?? const DynamicType();
+ inferrer.listener.propertyGet(this, fileOffset, member, inferredType);
+ return super.infer(inferrer, factory, typeContext);
+ }
+}
+
/// Shadow object for expressions that are introduced by the front end as part
/// of desugaring or the handling of error conditions.
///
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 99af76f..4ef4bdc 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -316,7 +316,6 @@
SourceOutlineSummary/example: Fail
StackOverflow/example: Fail
StaticAfterConst/script1: Fail
-SuperAsExpression/analyzerCode: Fail
SuperAsExpression/example: Fail
SuperAsIdentifier/analyzerCode: Fail
SuperAsIdentifier/example: Fail
@@ -336,7 +335,6 @@
SupertypeIsTypeVariable/analyzerCode: Fail
SupertypeIsTypeVariable/example: Fail
SwitchCaseFallThrough/example: Fail
-ThisAccessInFieldInitializer/analyzerCode: Fail
ThisAccessInFieldInitializer/example: Fail
ThisAsIdentifier/analyzerCode: Fail
ThisAsIdentifier/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 9d81316..d27a9c3 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -2057,6 +2057,8 @@
ThisAccessInFieldInitializer:
template: "Can't access 'this' in a field initializer to read '#name'."
+ analyzerCode: THIS_ACCESS_FROM_INITIALIZER
+ dart2jsCode: "*fatal*"
ThisAsIdentifier:
template: "Expected identifier, but got 'this'."
@@ -2067,6 +2069,8 @@
SuperAsExpression:
template: "Can't use 'super' as an expression."
tip: "To delegate a constructor to a super constructor, put the super call as an initializer."
+ analyzerCode: SUPER_AS_EXPRESSION
+ dart2jsCode: "*fatal*"
SwitchHasCaseAfterDefault:
template: "The default case should be the last case in a switch statement."
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index 3ba613b..45642d3 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -205,7 +205,7 @@
"ThisAccessGenerator(offset: 4, isInitializer: false, isSuper: false)",
new ThisAccessGenerator(helper, token, false));
check("IncompleteErrorGenerator(offset: 4, message: Unspecified)",
- new IncompleteErrorGenerator(helper, token, message));
+ new IncompleteErrorGenerator(helper, token, getter, message));
check("SendAccessGenerator(offset: 4, name: bar, arguments: (\"arg\"))",
new SendAccessGenerator(helper, token, name, arguments));
check("IncompletePropertyAccessGenerator(offset: 4, name: bar)",