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)",