Split ReadOnlyAccessGenerator

This prepares the generator to be implemented by the analyzer.

Change-Id: Idccd5af9aac79300186b3a07c636bb580bdd637c
Reviewed-on: https://dart-review.googlesource.com/56491
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
index 931b75c..5d03e7e 100644
--- a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
@@ -488,6 +488,16 @@
   int readOffset(AstNode node) => node.offset;
 
   @override
+  Generator<Expression, Statement, _Arguments> readOnlyAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
+      Token token,
+      Expression expression,
+      String plainNameForRead) {
+    // TODO(brianwilkerson) Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
   void resolveBreak(Statement target, BreakStatement user) {
     user.target = target;
   }
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 a5d63b8..7424ec5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1409,11 +1409,11 @@
         var fact =
             typePromoter.getFactForAccess(builder.target, functionNestingLevel);
         var scope = typePromoter.currentScope;
-        return new ReadOnlyAccessGenerator(
+        return new ReadOnlyAccessGenerator<Expression, Statement, Arguments>(
             this,
             token,
-            new ShadowVariableGet(builder.target, fact, scope)
-              ..fileOffset = charOffset,
+            toExpression(new ShadowVariableGet(builder.target, fact, scope)
+              ..fileOffset = charOffset),
             name);
       } else {
         return new VariableUseGenerator<Expression, Statement, Arguments>(
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 719bc04..e8c1a214 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -61,7 +61,6 @@
         IncompleteSendGenerator,
         LargeIntAccessGenerator,
         ParenthesizedExpressionGenerator,
-        ReadOnlyAccessGenerator,
         SendAccessGenerator,
         ThisAccessGenerator,
         UnresolvedNameGenerator,
@@ -636,3 +635,18 @@
     return type;
   }
 }
+
+abstract class ReadOnlyAccessGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  factory ReadOnlyAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Expression expression,
+      String plainNameForRead) {
+    return helper.forest
+        .readOnlyAccessGenerator(helper, token, expression, plainNameForRead);
+  }
+
+  @override
+  String get debugName => "ReadOnlyAccessGenerator";
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index b3fa099..a91e25a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -50,6 +50,7 @@
         KernelLoadLibraryGenerator,
         KernelNullAwarePropertyAccessGenerator,
         KernelPropertyAccessGenerator,
+        KernelReadOnlyAccessGenerator,
         KernelStaticAccessGenerator,
         KernelSuperIndexedAccessGenerator,
         KernelSuperPropertyAccessGenerator,
@@ -751,6 +752,16 @@
     return new KernelTypeUseGenerator(helper, token, prefix,
         declarationReferenceOffset, declaration, plainNameForRead);
   }
+
+  @override
+  KernelReadOnlyAccessGenerator readOnlyAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Expression expression,
+      String plainNameForRead) {
+    return new KernelReadOnlyAccessGenerator(
+        helper, token, expression, plainNameForRead);
+  }
 }
 
 class _VariablesDeclaration extends Statement {
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index ecfe7fa..1f2e6d7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -450,6 +450,12 @@
       TypeDeclarationBuilder declaration,
       String plainNameForRead);
 
+  Generator<Expression, Statement, Arguments> readOnlyAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Location location,
+      Expression expression,
+      String plainNameForRead);
+
   // TODO(ahe): Remove this method when all users are moved here.
   kernel.Arguments castArguments(Arguments arguments) {
     dynamic a = arguments;
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 b72a69d..101f608 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
@@ -54,6 +54,7 @@
         LoadLibraryGenerator,
         NullAwarePropertyAccessGenerator,
         PropertyAccessGenerator,
+        ReadOnlyAccessGenerator,
         StaticAccessGenerator,
         SuperIndexedAccessGenerator,
         SuperPropertyAccessGenerator,
@@ -1238,7 +1239,7 @@
   }
 }
 
-class KernelTypeUseGenerator extends ReadOnlyAccessGenerator
+class KernelTypeUseGenerator extends KernelReadOnlyAccessGenerator
     with TypeUseGenerator<Expression, Statement, Arguments> {
   /// The import prefix preceding the [declaration] reference, or `null` if
   /// the reference is not prefixed.
@@ -1253,7 +1254,7 @@
   final TypeDeclarationBuilder declaration;
 
   KernelTypeUseGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Token token,
       this.prefix,
       this.declarationReferenceOffset,
@@ -1344,6 +1345,63 @@
   }
 }
 
+class KernelReadOnlyAccessGenerator extends KernelGenerator
+    with ReadOnlyAccessGenerator<Expression, Statement, Arguments> {
+  @override
+  final String plainNameForRead;
+
+  Expression expression;
+
+  VariableDeclaration value;
+
+  KernelReadOnlyAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      this.expression,
+      this.plainNameForRead)
+      : super(helper, token);
+
+  @override
+  Expression _makeSimpleRead() => expression;
+
+  @override
+  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    value ??= new VariableDeclaration.forValue(expression);
+    return new VariableGet(value);
+  }
+
+  @override
+  Expression _makeWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    var write = makeInvalidWrite(value);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  @override
+  Expression _finish(
+          Expression body, ShadowComplexAssignment complexAssignment) =>
+      super._finish(makeLet(value, body), complexAssignment);
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
+        adjustForImplicitCall(plainNameForRead, offset),
+        isImplicitCall: true);
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", expression: ");
+    printNodeOn(expression, sink, syntheticNames: syntheticNames);
+    sink.write(", plainNameForRead: ");
+    sink.write(plainNameForRead);
+    sink.write(", value: ");
+    printNodeOn(value, sink, syntheticNames: syntheticNames);
+  }
+}
+
 Expression makeLet(VariableDeclaration variable, Expression body) {
   if (variable == null) return body;
   return new Let(variable, body);
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 9bda17f..f5d18f6 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
@@ -15,58 +15,6 @@
 /// superclass should use the forest API in a factory method.
 part of 'kernel_expression_generator.dart';
 
-class ReadOnlyAccessGenerator extends KernelGenerator {
-  final String plainNameForRead;
-
-  Expression expression;
-
-  VariableDeclaration value;
-
-  ReadOnlyAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
-      Token token,
-      this.expression,
-      this.plainNameForRead)
-      : super(helper, token);
-
-  String get debugName => "ReadOnlyAccessGenerator";
-
-  Expression _makeSimpleRead() => expression;
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    value ??= new VariableDeclaration.forValue(expression);
-    return new VariableGet(value);
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    var write = makeInvalidWrite(value);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  Expression _finish(
-          Expression body, ShadowComplexAssignment complexAssignment) =>
-      super._finish(makeLet(value, body), complexAssignment);
-
-  Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
-        adjustForImplicitCall(plainNameForRead, offset),
-        isImplicitCall: true);
-  }
-
-  @override
-  void printOn(StringSink sink) {
-    NameSystem syntheticNames = new NameSystem();
-    sink.write(", expression: ");
-    printNodeOn(expression, sink, syntheticNames: syntheticNames);
-    sink.write(", plainNameForRead: ");
-    sink.write(plainNameForRead);
-    sink.write(", value: ");
-    printNodeOn(value, sink, syntheticNames: syntheticNames);
-  }
-}
-
 class LargeIntAccessGenerator extends KernelGenerator {
   LargeIntAccessGenerator(
       ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper, Token token)
@@ -693,7 +641,7 @@
   }
 }
 
-class ParenthesizedExpressionGenerator extends ReadOnlyAccessGenerator {
+class ParenthesizedExpressionGenerator extends KernelReadOnlyAccessGenerator {
   ParenthesizedExpressionGenerator(
       ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
       Token token,
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 925fb30..7e61188 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -62,6 +62,7 @@
         KernelLoadLibraryGenerator,
         KernelNullAwarePropertyAccessGenerator,
         KernelPropertyAccessGenerator,
+        KernelReadOnlyAccessGenerator,
         KernelStaticAccessGenerator,
         KernelSuperIndexedAccessGenerator,
         KernelSuperPropertyAccessGenerator,
@@ -71,7 +72,6 @@
         KernelVariableUseGenerator,
         LargeIntAccessGenerator,
         ParenthesizedExpressionGenerator,
-        ReadOnlyAccessGenerator,
         SendAccessGenerator,
         ThisAccessGenerator,
         UnresolvedNameGenerator;
@@ -215,7 +215,7 @@
     check(
         "ReadOnlyAccessGenerator(offset: 4, expression: expression,"
         " plainNameForRead: foo, value: null)",
-        new ReadOnlyAccessGenerator(helper, token, expression, "foo"));
+        new KernelReadOnlyAccessGenerator(helper, token, expression, "foo"));
     check("LargeIntAccessGenerator(offset: 4, lexeme: myToken)",
         new LargeIntAccessGenerator(helper, token));
     check(