Split IndexedAccessGenerator and ThisIndexedAccessGenerator

This prepares the generators to be implemented by the analyzer.

Change-Id: I28ada82b602893b427c8d34df68b2c9a7f8439cf
Reviewed-on: https://dart-review.googlesource.com/56341
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 7df134c..8c06134 100644
--- a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
@@ -411,6 +411,7 @@
     throw new UnimplementedError();
   }
 
+  @override
   Generator<Expression, Statement, _Arguments> superPropertyAccessGenerator(
       ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
       Token token,
@@ -420,6 +421,29 @@
     // TODO(brianwilkerson): Implement this.
     throw new UnimplementedError();
   }
+
+  @override
+  Generator<Expression, Statement, _Arguments> indexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
+      Token token,
+      Expression receiver,
+      Expression index,
+      kernel.Procedure getter,
+      kernel.Procedure setter) {
+    // TODO(brianwilkerson): Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
+  Generator<Expression, Statement, _Arguments> thisIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
+      Token token,
+      Expression index,
+      kernel.Procedure getter,
+      kernel.Procedure setter) {
+    // TODO(brianwilkerson): Implement this.
+    throw new UnimplementedError();
+  }
 }
 
 /// A data holder used to conform to the [Forest] API.
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 40e2540..7cb74e5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2410,12 +2410,7 @@
           lookupInstanceMember(indexSetName, isSuper: true)));
     } else {
       push(IndexedAccessGenerator.make(
-          this,
-          openSquareBracket,
-          toKernelExpression(toValue(receiver)),
-          toKernelExpression(index),
-          null,
-          null));
+          this, openSquareBracket, toValue(receiver), index, null, null));
     }
   }
 
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 27f46c4..92b3ac2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -44,7 +44,6 @@
         IncompleteErrorGenerator,
         IncompletePropertyAccessGenerator,
         IncompleteSendGenerator,
-        IndexedAccessGenerator,
         LargeIntAccessGenerator,
         LoadLibraryGenerator,
         ParenthesizedExpressionGenerator,
@@ -53,7 +52,6 @@
         StaticAccessGenerator,
         SuperIndexedAccessGenerator,
         ThisAccessGenerator,
-        ThisIndexedAccessGenerator,
         TypeDeclarationAccessGenerator,
         UnresolvedNameGenerator,
         buildIsNull;
@@ -351,3 +349,67 @@
   @override
   String get debugName => "SuperPropertyAccessGenerator";
 }
+
+abstract class IndexedAccessGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  factory IndexedAccessGenerator.internal(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Expression receiver,
+      Expression index,
+      Procedure getter,
+      Procedure setter) {
+    return helper.forest
+        .indexedAccessGenerator(helper, token, receiver, index, getter, setter);
+  }
+
+  static Generator<Expression, Statement, Arguments>
+      make<Expression, Statement, Arguments>(
+          ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+          Token token,
+          Expression receiver,
+          Expression index,
+          Procedure getter,
+          Procedure setter) {
+    if (helper.forest.isThisExpression(receiver)) {
+      return new ThisIndexedAccessGenerator(
+          helper, token, index, getter, setter);
+    } else {
+      return new IndexedAccessGenerator.internal(
+          helper, token, receiver, index, getter, setter);
+    }
+  }
+
+  @override
+  String get plainNameForRead => "[]";
+
+  @override
+  String get plainNameForWrite => "[]=";
+
+  @override
+  String get debugName => "IndexedAccessGenerator";
+}
+
+/// Special case of [IndexedAccessGenerator] to avoid creating an indirect
+/// access to 'this'.
+abstract class ThisIndexedAccessGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  factory ThisIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Expression index,
+      Procedure getter,
+      Procedure setter) {
+    return helper.forest
+        .thisIndexedAccessGenerator(helper, token, index, getter, setter);
+  }
+
+  @override
+  String get plainNameForRead => "[]";
+
+  @override
+  String get plainNameForWrite => "[]=";
+
+  @override
+  String get debugName => "ThisIndexedAccessGenerator";
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index 73313bf..f4de49e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -26,6 +26,7 @@
         Member,
         Name,
         NamedExpression,
+        Procedure,
         Statement,
         SwitchCase,
         ThisExpression,
@@ -41,9 +42,11 @@
 
 import 'kernel_expression_generator.dart'
     show
+        KernelIndexedAccessGenerator,
         KernelNullAwarePropertyAccessGenerator,
         KernelPropertyAccessGenerator,
         KernelSuperPropertyAccessGenerator,
+        KernelThisIndexedAccessGenerator,
         KernelThisPropertyAccessGenerator,
         KernelVariableUseGenerator;
 
@@ -565,6 +568,29 @@
     return new KernelSuperPropertyAccessGenerator(
         helper, token, name, getter, setter);
   }
+
+  @override
+  KernelIndexedAccessGenerator indexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Expression receiver,
+      Expression index,
+      Procedure getter,
+      Procedure setter) {
+    return new KernelIndexedAccessGenerator.internal(
+        helper, token, receiver, index, getter, setter);
+  }
+
+  @override
+  KernelThisIndexedAccessGenerator thisIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Expression index,
+      Procedure getter,
+      Procedure setter) {
+    return new KernelThisIndexedAccessGenerator(
+        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 f5a8c9d..50f9c48 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -9,7 +9,8 @@
         Arguments, // TODO(ahe): Remove this import.
         DartType,
         Member,
-        Name;
+        Name,
+        Procedure;
 
 import 'body_builder.dart' show Identifier;
 
@@ -327,6 +328,21 @@
       kernel.Member getter,
       kernel.Member setter);
 
+  Generator<Expression, Statement, Arguments> indexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Location location,
+      Expression receiver,
+      Expression index,
+      kernel.Procedure getter,
+      kernel.Procedure setter);
+
+  Generator<Expression, Statement, Arguments> thisIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Location location,
+      Expression index,
+      kernel.Procedure getter,
+      kernel.Procedure 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 76e046d..218f9f9 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
@@ -52,9 +52,11 @@
     show
         ExpressionGenerator,
         Generator,
+        IndexedAccessGenerator,
         NullAwarePropertyAccessGenerator,
         PropertyAccessGenerator,
         SuperPropertyAccessGenerator,
+        ThisIndexedAccessGenerator,
         ThisPropertyAccessGenerator,
         VariableUseGenerator;
 
@@ -671,6 +673,277 @@
   }
 }
 
+class KernelIndexedAccessGenerator extends KernelGenerator
+    with IndexedAccessGenerator<Expression, Statement, Arguments> {
+  final Expression receiver;
+
+  final Expression index;
+
+  final Procedure getter;
+
+  final Procedure setter;
+
+  VariableDeclaration receiverVariable;
+
+  VariableDeclaration indexVariable;
+
+  KernelIndexedAccessGenerator.internal(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      this.receiver,
+      this.index,
+      this.getter,
+      this.setter)
+      : super(helper, token);
+
+  Expression indexAccess() {
+    indexVariable ??= new VariableDeclaration.forValue(index);
+    return new VariableGet(indexVariable)..fileOffset = offsetForToken(token);
+  }
+
+  Expression receiverAccess() {
+    // We cannot reuse the receiver if it is a variable since it might be
+    // reassigned in the index expression.
+    receiverVariable ??= new VariableDeclaration.forValue(receiver);
+    return new VariableGet(receiverVariable)
+      ..fileOffset = offsetForToken(token);
+  }
+
+  @override
+  Expression _makeSimpleRead() {
+    var read = new ShadowMethodInvocation(receiver, indexGetName,
+        forest.castArguments(forest.arguments(<Expression>[index], token)),
+        interfaceTarget: getter)
+      ..fileOffset = offsetForToken(token);
+    return read;
+  }
+
+  @override
+  Expression _makeSimpleWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    var write = new ShadowMethodInvocation(
+        receiver,
+        indexSetName,
+        forest
+            .castArguments(forest.arguments(<Expression>[index, value], token)),
+        interfaceTarget: setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  @override
+  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    var read = new ShadowMethodInvocation(
+        receiverAccess(),
+        indexGetName,
+        forest.castArguments(
+            forest.arguments(<Expression>[indexAccess()], token)),
+        interfaceTarget: getter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  @override
+  Expression _makeWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    var write = new ShadowMethodInvocation(
+        receiverAccess(),
+        indexSetName,
+        forest.castArguments(
+            forest.arguments(<Expression>[indexAccess(), value], token)),
+        interfaceTarget: setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  // TODO(dmitryas): remove this method after the "[]=" operator of the Context
+  // class is made to return a value.
+  Expression _makeWriteAndReturn(
+      Expression value, ShadowComplexAssignment complexAssignment) {
+    // The call to []= does not return the value like direct-style assignments
+    // do.  We need to bind the value in a let.
+    var valueVariable = new VariableDeclaration.forValue(value);
+    var write = new ShadowMethodInvocation(
+        receiverAccess(),
+        indexSetName,
+        forest.castArguments(forest.arguments(
+            <Expression>[indexAccess(), new VariableGet(valueVariable)],
+            token)),
+        interfaceTarget: setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    var dummy = new ShadowVariableDeclaration.forValue(
+        write, helper.functionNestingLevel);
+    return makeLet(
+        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+  }
+
+  @override
+  Expression _finish(
+      Expression body, ShadowComplexAssignment complexAssignment) {
+    return super._finish(
+        makeLet(receiverVariable, makeLet(indexVariable, body)),
+        complexAssignment);
+  }
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildMethodInvocation(
+        buildSimpleRead(), callName, arguments, forest.readOffset(arguments),
+        isImplicitCall: true);
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+      new ShadowIndexAssign(receiver, index, rhs);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", receiver: ");
+    printNodeOn(receiver, sink, syntheticNames: syntheticNames);
+    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(", receiverVariable: ");
+    printNodeOn(receiverVariable, sink, syntheticNames: syntheticNames);
+    sink.write(", indexVariable: ");
+    printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
+  }
+}
+
+class KernelThisIndexedAccessGenerator extends KernelGenerator
+    with ThisIndexedAccessGenerator<Expression, Statement, Arguments> {
+  final Expression index;
+
+  final Procedure getter;
+
+  final Procedure setter;
+
+  VariableDeclaration indexVariable;
+
+  KernelThisIndexedAccessGenerator(
+      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> 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);
+    var write = new ShadowMethodInvocation(
+        forest.thisExpression(token),
+        indexSetName,
+        forest.castArguments(forest.arguments(
+            <Expression>[indexAccess(), new VariableGet(valueVariable)],
+            token)),
+        interfaceTarget: setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    var dummy = new VariableDeclaration.forValue(write);
+    return makeLet(
+        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+  }
+
+  @override
+  Expression _makeSimpleRead() {
+    return new ShadowMethodInvocation(
+        forest.thisExpression(token),
+        indexGetName,
+        forest.castArguments(forest.arguments(<Expression>[index], token)),
+        interfaceTarget: getter)
+      ..fileOffset = offsetForToken(token);
+  }
+
+  @override
+  Expression _makeSimpleWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    var write = new ShadowMethodInvocation(
+        forest.thisExpression(token),
+        indexSetName,
+        forest
+            .castArguments(forest.arguments(<Expression>[index, value], token)),
+        interfaceTarget: setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  @override
+  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    var read = new ShadowMethodInvocation(
+        forest.thisExpression(token),
+        indexGetName,
+        forest.castArguments(
+            forest.arguments(<Expression>[indexAccess()], token)),
+        interfaceTarget: getter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  @override
+  Expression _makeWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    var write = new ShadowMethodInvocation(
+        forest.thisExpression(token),
+        indexSetName,
+        forest.castArguments(
+            forest.arguments(<Expression>[indexAccess(), value], token)),
+        interfaceTarget: 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);
+
+  @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 21085f5..46e7b2a 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,293 +15,6 @@
 /// superclass should use the forest API in a factory method.
 part of 'kernel_expression_generator.dart';
 
-class IndexedAccessGenerator extends KernelGenerator {
-  final Expression receiver;
-
-  final Expression index;
-
-  final Procedure getter;
-
-  final Procedure setter;
-
-  VariableDeclaration receiverVariable;
-
-  VariableDeclaration indexVariable;
-
-  IndexedAccessGenerator.internal(
-      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
-      Token token,
-      this.receiver,
-      this.index,
-      this.getter,
-      this.setter)
-      : super(helper, token);
-
-  static KernelGenerator make(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
-      Token token,
-      Expression receiver,
-      Expression index,
-      Procedure getter,
-      Procedure setter) {
-    if (helper.forest.isThisExpression(receiver)) {
-      return new ThisIndexedAccessGenerator(
-          helper, token, index, getter, setter);
-    } else {
-      return new IndexedAccessGenerator.internal(
-          helper, token, receiver, index, getter, setter);
-    }
-  }
-
-  String get plainNameForRead => "[]";
-
-  String get plainNameForWrite => "[]=";
-
-  String get debugName => "IndexedAccessGenerator";
-
-  Expression _makeSimpleRead() {
-    var read = new ShadowMethodInvocation(receiver, indexGetName,
-        forest.castArguments(forest.arguments(<Expression>[index], token)),
-        interfaceTarget: getter)
-      ..fileOffset = offsetForToken(token);
-    return read;
-  }
-
-  Expression _makeSimpleWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    var write = new ShadowMethodInvocation(
-        receiver,
-        indexSetName,
-        forest
-            .castArguments(forest.arguments(<Expression>[index, value], token)),
-        interfaceTarget: setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  receiverAccess() {
-    // We cannot reuse the receiver if it is a variable since it might be
-    // reassigned in the index expression.
-    receiverVariable ??= new VariableDeclaration.forValue(receiver);
-    return new VariableGet(receiverVariable)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  indexAccess() {
-    indexVariable ??= new VariableDeclaration.forValue(index);
-    return new VariableGet(indexVariable)..fileOffset = offsetForToken(token);
-  }
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    var read = new ShadowMethodInvocation(
-        receiverAccess(),
-        indexGetName,
-        forest.castArguments(
-            forest.arguments(<Expression>[indexAccess()], token)),
-        interfaceTarget: getter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    var write = new ShadowMethodInvocation(
-        receiverAccess(),
-        indexSetName,
-        forest.castArguments(
-            forest.arguments(<Expression>[indexAccess(), value], token)),
-        interfaceTarget: setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  // TODO(dmitryas): remove this method after the "[]=" operator of the Context
-  // class is made to return a value.
-  _makeWriteAndReturn(
-      Expression value, ShadowComplexAssignment complexAssignment) {
-    // The call to []= does not return the value like direct-style assignments
-    // do.  We need to bind the value in a let.
-    var valueVariable = new VariableDeclaration.forValue(value);
-    var write = new ShadowMethodInvocation(
-        receiverAccess(),
-        indexSetName,
-        forest.castArguments(forest.arguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)],
-            token)),
-        interfaceTarget: setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    var dummy = new ShadowVariableDeclaration.forValue(
-        write, helper.functionNestingLevel);
-    return makeLet(
-        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
-  }
-
-  Expression _finish(
-      Expression body, ShadowComplexAssignment complexAssignment) {
-    return super._finish(
-        makeLet(receiverVariable, makeLet(indexVariable, body)),
-        complexAssignment);
-  }
-
-  Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildMethodInvocation(
-        buildSimpleRead(), callName, arguments, forest.readOffset(arguments),
-        isImplicitCall: true);
-  }
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
-      new ShadowIndexAssign(receiver, index, rhs);
-
-  @override
-  void printOn(StringSink sink) {
-    NameSystem syntheticNames = new NameSystem();
-    sink.write(", receiver: ");
-    printNodeOn(receiver, sink, syntheticNames: syntheticNames);
-    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(", receiverVariable: ");
-    printNodeOn(receiverVariable, sink, syntheticNames: syntheticNames);
-    sink.write(", indexVariable: ");
-    printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
-  }
-}
-
-/// Special case of [IndexedAccessGenerator] to avoid creating an indirect
-/// access to 'this'.
-class ThisIndexedAccessGenerator extends KernelGenerator {
-  final Expression index;
-
-  final Procedure getter;
-
-  final Procedure setter;
-
-  VariableDeclaration indexVariable;
-
-  ThisIndexedAccessGenerator(
-      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 => "ThisIndexedAccessGenerator";
-
-  Expression _makeSimpleRead() {
-    return new ShadowMethodInvocation(
-        forest.thisExpression(token),
-        indexGetName,
-        forest.castArguments(forest.arguments(<Expression>[index], token)),
-        interfaceTarget: getter)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  Expression _makeSimpleWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    var write = new ShadowMethodInvocation(
-        forest.thisExpression(token),
-        indexSetName,
-        forest
-            .castArguments(forest.arguments(<Expression>[index, value], token)),
-        interfaceTarget: setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  indexAccess() {
-    indexVariable ??= new VariableDeclaration.forValue(index);
-    return new VariableGet(indexVariable);
-  }
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    var read = new ShadowMethodInvocation(
-        forest.thisExpression(token),
-        indexGetName,
-        forest.castArguments(
-            forest.arguments(<Expression>[indexAccess()], token)),
-        interfaceTarget: getter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    var write = new ShadowMethodInvocation(
-        forest.thisExpression(token),
-        indexSetName,
-        forest.castArguments(
-            forest.arguments(<Expression>[indexAccess(), value], token)),
-        interfaceTarget: setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  _makeWriteAndReturn(
-      Expression value, ShadowComplexAssignment complexAssignment) {
-    var valueVariable = new VariableDeclaration.forValue(value);
-    var write = new ShadowMethodInvocation(
-        forest.thisExpression(token),
-        indexSetName,
-        forest.castArguments(forest.arguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)],
-            token)),
-        interfaceTarget: 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);
-
-  @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 SuperIndexedAccessGenerator extends KernelGenerator {
   final Expression index;
 
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 c9c77ea..53b70fe 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -58,10 +58,11 @@
         DelayedPostfixIncrement,
         IncompleteErrorGenerator,
         IncompletePropertyAccessGenerator,
-        IndexedAccessGenerator,
+        KernelIndexedAccessGenerator,
         KernelNullAwarePropertyAccessGenerator,
         KernelPropertyAccessGenerator,
         KernelSuperPropertyAccessGenerator,
+        KernelThisIndexedAccessGenerator,
         KernelThisPropertyAccessGenerator,
         KernelVariableUseGenerator,
         LargeIntAccessGenerator,
@@ -72,7 +73,6 @@
         StaticAccessGenerator,
         SuperIndexedAccessGenerator,
         ThisAccessGenerator,
-        ThisIndexedAccessGenerator,
         TypeDeclarationAccessGenerator,
         UnresolvedNameGenerator;
 
@@ -176,12 +176,13 @@
         "IndexedAccessGenerator(offset: 4, receiver: expression, index: index,"
         " getter: $uri::myGetter, setter: $uri::mySetter,"
         " receiverVariable: null, indexVariable: null)",
-        new IndexedAccessGenerator.internal(
+        new KernelIndexedAccessGenerator.internal(
             helper, token, expression, index, getter, setter));
     check(
         "ThisIndexedAccessGenerator(offset: 4, index: index,"
         " getter: $uri::myGetter, setter: $uri::mySetter, indexVariable: null)",
-        new ThisIndexedAccessGenerator(helper, token, index, getter, setter));
+        new KernelThisIndexedAccessGenerator(
+            helper, token, index, getter, setter));
     check(
         "SuperIndexedAccessGenerator(offset: 4, index: index,"
         " getter: $uri::myGetter, setter: $uri::mySetter, indexVariable: null)",