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>, &hellip;, 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)",