Split StaticAccessGenerator

This prepares the generator to be implemented by the analyzer.

Change-Id: I99a1e1365da67a867f6c4ed5883649f157306d92
Reviewed-on: https://dart-review.googlesource.com/56502
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 83d0a21..9a748ad 100644
--- a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
@@ -499,6 +499,16 @@
   }
 
   @override
+  Generator<Expression, Statement, _Arguments> staticAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
+      Token token,
+      kernel.Member getter,
+      kernel.Member setter) {
+    // TODO(brianwilkerson) Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
   Expression stringConcatenationExpression(
           List<Expression> strings, Token location) =>
       astFactory.adjacentStrings(strings.cast<StringLiteral>());
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 c9047b5..35bd171 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1443,8 +1443,9 @@
           this, token, n, getter, setter);
     } else if (builder.isRegularMethod) {
       assert(builder.isStatic || builder.isTopLevel);
-      StaticAccessGenerator generator =
-          new StaticAccessGenerator(this, token, builder.target, null);
+      StaticAccessGenerator<Expression, Statement, Arguments> generator =
+          new StaticAccessGenerator<Expression, Statement, Arguments>(
+              this, token, builder.target, null);
       return (prefix?.deferred == true)
           ? new DeferredAccessGenerator(this, token, prefix, generator)
           : generator;
@@ -1471,8 +1472,9 @@
       } else if (builder.isField && !builder.isFinal) {
         setter = builder;
       }
-      StaticAccessGenerator generator =
-          new StaticAccessGenerator.fromBuilder(this, builder, token, setter);
+      StaticAccessGenerator<Expression, Statement, Arguments> generator =
+          new StaticAccessGenerator<Expression, Statement,
+              Arguments>.fromBuilder(this, builder, token, setter);
       if (constantContext != ConstantContext.none) {
         Member readTarget = generator.readTarget;
         if (!(readTarget is Field && readTarget.isConst ||
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 421b6b8..fbf5cb1 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -7,6 +7,8 @@
 
 import '../../scanner/token.dart' show Token;
 
+import '../builder/builder.dart' show AccessErrorBuilder, Builder;
+
 import '../constant_context.dart' show ConstantContext;
 
 import '../fasta_codes.dart'
@@ -16,7 +18,7 @@
 
 import '../parser.dart' show lengthForToken, offsetForToken;
 
-import '../problems.dart' show unsupported;
+import '../problems.dart' show unhandled, unsupported;
 
 import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
 
@@ -49,7 +51,6 @@
         ParenthesizedExpressionGenerator,
         ReadOnlyAccessGenerator,
         SendAccessGenerator,
-        StaticAccessGenerator,
         ThisAccessGenerator,
         TypeDeclarationAccessGenerator,
         UnresolvedNameGenerator,
@@ -426,3 +427,49 @@
 
   String get debugName => "SuperIndexedAccessGenerator";
 }
+
+abstract class StaticAccessGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  factory StaticAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Member readTarget,
+      Member writeTarget) {
+    return helper.forest
+        .staticAccessGenerator(helper, token, readTarget, writeTarget);
+  }
+
+  factory StaticAccessGenerator.fromBuilder(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Builder builder,
+      Token token,
+      Builder builderSetter) {
+    if (builder is AccessErrorBuilder) {
+      AccessErrorBuilder error = builder;
+      builder = error.builder;
+      // We should only see an access error here if we've looked up a setter
+      // when not explicitly looking for a setter.
+      assert(builder.isSetter);
+    } else if (builder.target == null) {
+      return unhandled(
+          "${builder.runtimeType}",
+          "StaticAccessGenerator.fromBuilder",
+          offsetForToken(token),
+          helper.uri);
+    }
+    Member getter = builder.target.hasGetter ? builder.target : null;
+    Member setter = builder.target.hasSetter ? builder.target : null;
+    if (setter == null) {
+      if (builderSetter?.target?.hasSetter ?? false) {
+        setter = builderSetter.target;
+      }
+    }
+    return new StaticAccessGenerator<Expression, Statement, Arguments>(
+        helper, token, getter, setter);
+  }
+
+  Member get readTarget;
+
+  @override
+  String get debugName => "StaticAccessGenerator";
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index de4d5f2..bfc2d62 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -46,6 +46,7 @@
 import 'kernel_expression_generator.dart'
     show
         KernelIndexedAccessGenerator,
+        KernelStaticAccessGenerator,
         KernelSuperIndexedAccessGenerator,
         KernelNullAwarePropertyAccessGenerator,
         KernelPropertyAccessGenerator,
@@ -702,6 +703,15 @@
     return new KernelSuperIndexedAccessGenerator(
         helper, token, index, getter, setter);
   }
+
+  @override
+  KernelStaticAccessGenerator staticAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Member getter,
+      Member setter) {
+    return new KernelStaticAccessGenerator(helper, token, getter, setter);
+  }
 }
 
 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 08bb427..83e6eef 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -419,6 +419,12 @@
       kernel.Member getter,
       kernel.Member setter);
 
+  Generator<Expression, Statement, Arguments> staticAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Location location,
+      kernel.Member getter,
+      kernel.Member setter);
+
   // 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 1b99891..8c06e5e 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
@@ -42,8 +42,6 @@
 
 import '../problems.dart' show unhandled, unsupported;
 
-import '../scope.dart' show AccessErrorBuilder;
-
 import 'body_builder.dart' show Identifier, noLocation;
 
 import 'constness.dart' show Constness;
@@ -54,8 +52,9 @@
         Generator,
         IndexedAccessGenerator,
         NullAwarePropertyAccessGenerator,
-        SuperIndexedAccessGenerator,
         PropertyAccessGenerator,
+        StaticAccessGenerator,
+        SuperIndexedAccessGenerator,
         SuperPropertyAccessGenerator,
         ThisIndexedAccessGenerator,
         ThisPropertyAccessGenerator,
@@ -277,7 +276,7 @@
   final DartType promotedType;
 
   KernelVariableUseGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, Arguments> helper,
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Token token,
       this.variable,
       this.promotedType)
@@ -343,7 +342,7 @@
   VariableDeclaration _receiverVariable;
 
   KernelPropertyAccessGenerator.internal(
-      ExpressionGeneratorHelper<dynamic, dynamic, Arguments> helper,
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Token token,
       this.receiver,
       this.name,
@@ -511,7 +510,7 @@
   final DartType type;
 
   KernelNullAwarePropertyAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Token token,
       this.receiverExpression,
       this.name,
@@ -603,7 +602,7 @@
   final Member setter;
 
   KernelSuperPropertyAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Token token,
       this.name,
       this.getter,
@@ -832,7 +831,7 @@
   VariableDeclaration indexVariable;
 
   KernelThisIndexedAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Token token,
       this.index,
       this.getter,
@@ -1085,6 +1084,83 @@
   }
 }
 
+class KernelStaticAccessGenerator extends KernelGenerator
+    with StaticAccessGenerator<Expression, Statement, Arguments> {
+  @override
+  final Member readTarget;
+
+  final Member writeTarget;
+
+  KernelStaticAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      this.readTarget,
+      this.writeTarget)
+      : assert(readTarget != null || writeTarget != null),
+        super(helper, token);
+
+  @override
+  String get plainNameForRead => (readTarget ?? writeTarget).name.name;
+
+  @override
+  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    if (readTarget == null) {
+      return makeInvalidRead();
+    } else {
+      var read = helper.makeStaticGet(readTarget, token);
+      complexAssignment?.read = read;
+      return read;
+    }
+  }
+
+  @override
+  Expression _makeWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    Expression write;
+    if (writeTarget == null) {
+      write = makeInvalidWrite(value);
+    } else {
+      write = new StaticSet(writeTarget, value);
+      complexAssignment?.write = write;
+    }
+    write.fileOffset = offsetForToken(token);
+    return write;
+  }
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    if (helper.constantContext != ConstantContext.none &&
+        !helper.isIdentical(readTarget)) {
+      helper.deprecated_addCompileTimeError(
+          offset, "Not a constant expression.");
+    }
+    if (readTarget == null || isFieldOrGetter(readTarget)) {
+      return helper.buildMethodInvocation(buildSimpleRead(), callName,
+          arguments, offset + (readTarget?.name?.name?.length ?? 0),
+          // This isn't a constant expression, but we have checked if a
+          // constant expression error should be emitted already.
+          isConstantExpression: true,
+          isImplicitCall: true);
+    } else {
+      return helper.buildStaticInvocation(readTarget, arguments,
+          charOffset: offset);
+    }
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+      new ShadowStaticAssignment(rhs);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", readTarget: ");
+    printQualifiedNameOn(readTarget, sink, syntheticNames: syntheticNames);
+    sink.write(", writeTarget: ");
+    printQualifiedNameOn(writeTarget, 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 29ed358..fc82784 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,107 +15,6 @@
 /// superclass should use the forest API in a factory method.
 part of 'kernel_expression_generator.dart';
 
-class StaticAccessGenerator extends KernelGenerator {
-  final Member readTarget;
-
-  final Member writeTarget;
-
-  StaticAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
-      Token token,
-      this.readTarget,
-      this.writeTarget)
-      : assert(readTarget != null || writeTarget != null),
-        super(helper, token);
-
-  factory StaticAccessGenerator.fromBuilder(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
-      Builder builder,
-      Token token,
-      Builder builderSetter) {
-    if (builder is AccessErrorBuilder) {
-      AccessErrorBuilder error = builder;
-      builder = error.builder;
-      // We should only see an access error here if we've looked up a setter
-      // when not explicitly looking for a setter.
-      assert(builder.isSetter);
-    } else if (builder.target == null) {
-      return unhandled(
-          "${builder.runtimeType}",
-          "StaticAccessGenerator.fromBuilder",
-          offsetForToken(token),
-          helper.uri);
-    }
-    Member getter = builder.target.hasGetter ? builder.target : null;
-    Member setter = builder.target.hasSetter ? builder.target : null;
-    if (setter == null) {
-      if (builderSetter?.target?.hasSetter ?? false) {
-        setter = builderSetter.target;
-      }
-    }
-    return new StaticAccessGenerator(helper, token, getter, setter);
-  }
-
-  String get plainNameForRead => (readTarget ?? writeTarget).name.name;
-
-  String get debugName => "StaticAccessGenerator";
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    if (readTarget == null) {
-      return makeInvalidRead();
-    } else {
-      var read = helper.makeStaticGet(readTarget, token);
-      complexAssignment?.read = read;
-      return read;
-    }
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    Expression write;
-    if (writeTarget == null) {
-      write = makeInvalidWrite(value);
-    } else {
-      write = new StaticSet(writeTarget, value);
-      complexAssignment?.write = write;
-    }
-    write.fileOffset = offsetForToken(token);
-    return write;
-  }
-
-  Expression doInvocation(int offset, Arguments arguments) {
-    if (helper.constantContext != ConstantContext.none &&
-        !helper.isIdentical(readTarget)) {
-      helper.deprecated_addCompileTimeError(
-          offset, "Not a constant expression.");
-    }
-    if (readTarget == null || isFieldOrGetter(readTarget)) {
-      return helper.buildMethodInvocation(buildSimpleRead(), callName,
-          arguments, offset + (readTarget?.name?.name?.length ?? 0),
-          // This isn't a constant expression, but we have checked if a
-          // constant expression error should be emitted already.
-          isConstantExpression: true,
-          isImplicitCall: true);
-    } else {
-      return helper.buildStaticInvocation(readTarget, arguments,
-          charOffset: offset);
-    }
-  }
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
-      new ShadowStaticAssignment(rhs);
-
-  @override
-  void printOn(StringSink sink) {
-    NameSystem syntheticNames = new NameSystem();
-    sink.write(", readTarget: ");
-    printQualifiedNameOn(readTarget, sink, syntheticNames: syntheticNames);
-    sink.write(", writeTarget: ");
-    printQualifiedNameOn(writeTarget, sink, syntheticNames: syntheticNames);
-  }
-}
-
 class LoadLibraryGenerator extends KernelGenerator {
   final LoadLibraryBuilder builder;
 
@@ -168,8 +67,11 @@
       ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
       Token token,
       this.builder,
-      this.generator)
-      : super(helper, token);
+      Generator<dynamic, dynamic, dynamic>
+          generator // TODO(ahe): Should be this.generator
+      )
+      : this.generator = generator,
+        super(helper, token);
 
   String get plainNameForRead {
     return unsupported(
@@ -1014,8 +916,8 @@
         } else if (builder.isField && !builder.isFinal) {
           setter = builder;
         }
-        generator = new StaticAccessGenerator.fromBuilder(
-            helper, builder, send.token, setter);
+        generator = new StaticAccessGenerator<Expression, Statement,
+            Arguments>.fromBuilder(helper, builder, send.token, setter);
       }
 
       return arguments == null
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 94388c1..ce90b4b 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -61,6 +61,7 @@
         KernelIndexedAccessGenerator,
         KernelNullAwarePropertyAccessGenerator,
         KernelPropertyAccessGenerator,
+        KernelStaticAccessGenerator,
         KernelSuperIndexedAccessGenerator,
         KernelSuperPropertyAccessGenerator,
         KernelThisIndexedAccessGenerator,
@@ -71,7 +72,6 @@
         ParenthesizedExpressionGenerator,
         ReadOnlyAccessGenerator,
         SendAccessGenerator,
-        StaticAccessGenerator,
         ThisAccessGenerator,
         TypeDeclarationAccessGenerator,
         UnresolvedNameGenerator;
@@ -191,7 +191,7 @@
     check(
         "StaticAccessGenerator(offset: 4, readTarget: $uri::myGetter,"
         " writeTarget: $uri::mySetter)",
-        new StaticAccessGenerator(helper, token, getter, setter));
+        new KernelStaticAccessGenerator(helper, token, getter, setter));
     check(
         "LoadLibraryGenerator(offset: 4,"
         " builder: Instance of 'LoadLibraryBuilder')",