Split SuperIndexedAccessGenerator

This prepares the generator to be implemented by the analyzer.

Change-Id: Ia962668e1327b53af968be9efdc41ea6b124b4d0
Reviewed-on: https://dart-review.googlesource.com/56482
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 b9d71b0..83d0a21 100644
--- a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
@@ -297,7 +297,7 @@
       Expression index,
       kernel.Procedure getter,
       kernel.Procedure setter) {
-    // TODO(brianwilkerson): Implement this.
+    // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
   }
 
@@ -443,7 +443,7 @@
       kernel.Member getter,
       kernel.Member setter,
       kernel.DartType type) {
-    // TODO(brianwilkerson): Implement this.
+    // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
   }
 
@@ -461,7 +461,7 @@
       kernel.Name name,
       kernel.Member getter,
       kernel.Member setter) {
-    // TODO(brianwilkerson): Implement this.
+    // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
   }
 
@@ -504,13 +504,24 @@
       astFactory.adjacentStrings(strings.cast<StringLiteral>());
 
   @override
+  Generator<Expression, Statement, _Arguments> superIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
+      Token token,
+      Expression index,
+      kernel.Member getter,
+      kernel.Member setter) {
+    // TODO(brianwilkerson) Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
   Generator<Expression, Statement, _Arguments> superPropertyAccessGenerator(
       ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
       Token token,
       kernel.Name name,
       kernel.Member getter,
       kernel.Member setter) {
-    // TODO(brianwilkerson): Implement this.
+    // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
   }
 
@@ -528,7 +539,7 @@
       Expression index,
       kernel.Procedure getter,
       kernel.Procedure setter) {
-    // TODO(brianwilkerson): Implement this.
+    // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
   }
 
@@ -539,7 +550,7 @@
       kernel.Name name,
       kernel.Member getter,
       kernel.Member setter) {
-    // TODO(brianwilkerson): Implement this.
+    // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
   }
 
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 92b3ac2..24c9ff1 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -50,7 +50,6 @@
         ReadOnlyAccessGenerator,
         SendAccessGenerator,
         StaticAccessGenerator,
-        SuperIndexedAccessGenerator,
         ThisAccessGenerator,
         TypeDeclarationAccessGenerator,
         UnresolvedNameGenerator,
@@ -413,3 +412,22 @@
   @override
   String get debugName => "ThisIndexedAccessGenerator";
 }
+
+abstract class SuperIndexedAccessGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  factory SuperIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Expression index,
+      Member getter,
+      Member setter) {
+    return helper.forest
+        .superIndexedAccessGenerator(helper, token, index, getter, setter);
+  }
+
+  String get plainNameForRead => "[]";
+
+  String get plainNameForWrite => "[]=";
+
+  String get debugName => "SuperIndexedAccessGenerator";
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index 31cf926..de4d5f2 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,
+        KernelSuperIndexedAccessGenerator,
         KernelNullAwarePropertyAccessGenerator,
         KernelPropertyAccessGenerator,
         KernelSuperPropertyAccessGenerator,
@@ -690,6 +691,17 @@
     return new KernelThisIndexedAccessGenerator(
         helper, token, index, getter, setter);
   }
+
+  @override
+  KernelSuperIndexedAccessGenerator superIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Expression index,
+      Member getter,
+      Member setter) {
+    return new KernelSuperIndexedAccessGenerator(
+        helper, token, index, 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 6c01ea6..08bb427 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -412,6 +412,13 @@
       kernel.Procedure getter,
       kernel.Procedure setter);
 
+  Generator<Expression, Statement, Arguments> superIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Location location,
+      Expression index,
+      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 218f9f9..1b99891 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 @@
         Generator,
         IndexedAccessGenerator,
         NullAwarePropertyAccessGenerator,
+        SuperIndexedAccessGenerator,
         PropertyAccessGenerator,
         SuperPropertyAccessGenerator,
         ThisIndexedAccessGenerator,
@@ -944,6 +945,146 @@
   }
 }
 
+class KernelSuperIndexedAccessGenerator extends KernelGenerator
+    with SuperIndexedAccessGenerator<Expression, Statement, Arguments> {
+  final Expression index;
+
+  final Member getter;
+
+  final Member setter;
+
+  VariableDeclaration indexVariable;
+
+  KernelSuperIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      this.index,
+      this.getter,
+      this.setter)
+      : super(helper, token);
+
+  Expression indexAccess() {
+    indexVariable ??= new VariableDeclaration.forValue(index);
+    return new VariableGet(indexVariable);
+  }
+
+  Expression _makeWriteAndReturn(
+      Expression value, ShadowComplexAssignment complexAssignment) {
+    var valueVariable = new VariableDeclaration.forValue(value);
+    if (setter == null) {
+      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
+          isSuper: true);
+    }
+    var write = new SuperMethodInvocation(
+        indexSetName,
+        forest.castArguments(forest.arguments(
+            <Expression>[indexAccess(), new VariableGet(valueVariable)],
+            token)),
+        setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    var dummy = new VariableDeclaration.forValue(write);
+    return makeLet(
+        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+  }
+
+  @override
+  Expression _makeSimpleRead() {
+    if (getter == null) {
+      helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
+          isSuper: true);
+    }
+    // TODO(ahe): Use [DirectMethodInvocation] when possible.
+    return new ShadowSuperMethodInvocation(
+        indexGetName,
+        forest.castArguments(forest.arguments(<Expression>[index], token)),
+        getter)
+      ..fileOffset = offsetForToken(token);
+  }
+
+  @override
+  Expression _makeSimpleWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    if (setter == null) {
+      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
+          isSuper: true);
+    }
+    var write = new SuperMethodInvocation(
+        indexSetName,
+        forest
+            .castArguments(forest.arguments(<Expression>[index, value], token)),
+        setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  @override
+  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    if (getter == null) {
+      helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
+          isSuper: true);
+    }
+    var read = new SuperMethodInvocation(
+        indexGetName,
+        forest.castArguments(
+            forest.arguments(<Expression>[indexAccess()], token)),
+        getter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  @override
+  Expression _makeWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    if (setter == null) {
+      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
+          isSuper: true);
+    }
+    var write = new SuperMethodInvocation(
+        indexSetName,
+        forest.castArguments(
+            forest.arguments(<Expression>[indexAccess(), value], token)),
+        setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  @override
+  Expression _finish(
+      Expression body, ShadowComplexAssignment complexAssignment) {
+    return super._finish(makeLet(indexVariable, body), complexAssignment);
+  }
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildMethodInvocation(
+        buildSimpleRead(), callName, arguments, offset,
+        isImplicitCall: true);
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+      new ShadowIndexAssign(null, index, rhs, isSuper: true);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", index: ");
+    printNodeOn(index, sink, syntheticNames: syntheticNames);
+    sink.write(", getter: ");
+    printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+    sink.write(", setter: ");
+    printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+    sink.write(", indexVariable: ");
+    printNodeOn(indexVariable, 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 46e7b2a..85668e3 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,145 +15,6 @@
 /// superclass should use the forest API in a factory method.
 part of 'kernel_expression_generator.dart';
 
-class SuperIndexedAccessGenerator extends KernelGenerator {
-  final Expression index;
-
-  final Member getter;
-
-  final Member setter;
-
-  VariableDeclaration indexVariable;
-
-  SuperIndexedAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
-      Token token,
-      this.index,
-      this.getter,
-      this.setter)
-      : super(helper, token);
-
-  String get plainNameForRead => "[]";
-
-  String get plainNameForWrite => "[]=";
-
-  String get debugName => "SuperIndexedAccessGenerator";
-
-  indexAccess() {
-    indexVariable ??= new VariableDeclaration.forValue(index);
-    return new VariableGet(indexVariable);
-  }
-
-  Expression _makeSimpleRead() {
-    if (getter == null) {
-      helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
-          isSuper: true);
-    }
-    // TODO(ahe): Use [DirectMethodInvocation] when possible.
-    return new ShadowSuperMethodInvocation(
-        indexGetName,
-        forest.castArguments(forest.arguments(<Expression>[index], token)),
-        getter)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  Expression _makeSimpleWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    if (setter == null) {
-      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
-          isSuper: true);
-    }
-    var write = new SuperMethodInvocation(
-        indexSetName,
-        forest
-            .castArguments(forest.arguments(<Expression>[index, value], token)),
-        setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    if (getter == null) {
-      helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
-          isSuper: true);
-    }
-    var read = new SuperMethodInvocation(
-        indexGetName,
-        forest.castArguments(
-            forest.arguments(<Expression>[indexAccess()], token)),
-        getter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    if (setter == null) {
-      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
-          isSuper: true);
-    }
-    var write = new SuperMethodInvocation(
-        indexSetName,
-        forest.castArguments(
-            forest.arguments(<Expression>[indexAccess(), value], token)),
-        setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  _makeWriteAndReturn(
-      Expression value, ShadowComplexAssignment complexAssignment) {
-    var valueVariable = new VariableDeclaration.forValue(value);
-    if (setter == null) {
-      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
-          isSuper: true);
-    }
-    var write = new SuperMethodInvocation(
-        indexSetName,
-        forest.castArguments(forest.arguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)],
-            token)),
-        setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    var dummy = new VariableDeclaration.forValue(write);
-    return makeLet(
-        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
-  }
-
-  Expression _finish(
-      Expression body, ShadowComplexAssignment complexAssignment) {
-    return super._finish(makeLet(indexVariable, body), complexAssignment);
-  }
-
-  Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildMethodInvocation(
-        buildSimpleRead(), callName, arguments, offset,
-        isImplicitCall: true);
-  }
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
-      new ShadowIndexAssign(null, index, rhs, isSuper: true);
-
-  @override
-  void printOn(StringSink sink) {
-    NameSystem syntheticNames = new NameSystem();
-    sink.write(", index: ");
-    printNodeOn(index, sink, syntheticNames: syntheticNames);
-    sink.write(", getter: ");
-    printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
-    sink.write(", setter: ");
-    printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
-    sink.write(", indexVariable: ");
-    printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
-  }
-}
-
 class StaticAccessGenerator extends KernelGenerator {
   final Member readTarget;
 
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 53b70fe..2b79891 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,
+        KernelSuperIndexedAccessGenerator,
         KernelSuperPropertyAccessGenerator,
         KernelThisIndexedAccessGenerator,
         KernelThisPropertyAccessGenerator,
@@ -71,7 +72,6 @@
         ReadOnlyAccessGenerator,
         SendAccessGenerator,
         StaticAccessGenerator,
-        SuperIndexedAccessGenerator,
         ThisAccessGenerator,
         TypeDeclarationAccessGenerator,
         UnresolvedNameGenerator;
@@ -186,7 +186,8 @@
     check(
         "SuperIndexedAccessGenerator(offset: 4, index: index,"
         " getter: $uri::myGetter, setter: $uri::mySetter, indexVariable: null)",
-        new SuperIndexedAccessGenerator(helper, token, index, getter, setter));
+        new KernelSuperIndexedAccessGenerator(
+            helper, token, index, getter, setter));
     check(
         "StaticAccessGenerator(offset: 4, readTarget: $uri::myGetter,"
         " writeTarget: $uri::mySetter)",