mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 21:31:20 +00:00
Change Accessor(s) to use AstFactory to create MethodInvocation, PropertyGet/Set.
R=ahe@google.com, paulberry@google.com BUG= Review-Url: https://codereview.chromium.org/2857133004 .
This commit is contained in:
parent
374871da75
commit
b567aeaeef
|
@ -58,5 +58,6 @@
|
|||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Dart SDK" level="application" />
|
||||
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||
<orderEntry type="library" name="Dart Packages" level="project" />
|
||||
</component>
|
||||
</module>
|
|
@ -47,5 +47,6 @@
|
|||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Dart SDK" level="application" />
|
||||
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||
<orderEntry type="library" name="Dart Packages" level="project" />
|
||||
</component>
|
||||
</module>
|
|
@ -21,5 +21,6 @@
|
|||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Dart SDK" level="application" />
|
||||
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||
<orderEntry type="library" name="Dart Packages" level="project" />
|
||||
</component>
|
||||
</module>
|
|
@ -107,12 +107,25 @@ abstract class AstFactory<V> {
|
|||
{DartType keyType: const DynamicType(),
|
||||
DartType valueType: const DynamicType()});
|
||||
|
||||
/// Creates a method invocation of form `x.foo(y)`.
|
||||
MethodInvocation methodInvocation(
|
||||
Expression receiver, Name name, Arguments arguments,
|
||||
[Procedure interfaceTarget]);
|
||||
|
||||
/// Create an expression of form `!x`.
|
||||
Not not(Token token, Expression operand);
|
||||
|
||||
/// Creates a null literal expression.
|
||||
NullLiteral nullLiteral(Token token);
|
||||
|
||||
/// Creates a read of a property.
|
||||
PropertyGet propertyGet(Expression receiver, Name name,
|
||||
[Member interfaceTarget]);
|
||||
|
||||
/// Creates a write of a property.
|
||||
PropertySet propertySet(Expression receiver, Name name, Expression value,
|
||||
[Member interfaceTarget]);
|
||||
|
||||
/// Create a `rethrow` expression.
|
||||
Rethrow rethrowExpression(Token keyword);
|
||||
|
||||
|
|
|
@ -621,7 +621,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
return receiver.doInvocation(charOffset, arguments);
|
||||
} else {
|
||||
return buildMethodInvocation(
|
||||
toValue(receiver), callName, arguments, charOffset);
|
||||
astFactory, toValue(receiver), callName, arguments, charOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -684,8 +684,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
return buildCompileTimeError(
|
||||
"Not an operator: '$operator'.", token.charOffset);
|
||||
} else {
|
||||
Expression result =
|
||||
makeBinary(a, new Name(operator), null, b, offset: token.charOffset);
|
||||
Expression result = makeBinary(astFactory, a, new Name(operator), null, b,
|
||||
offset: token.charOffset);
|
||||
if (isSuper) {
|
||||
result = toSuperMethodInvocation(result);
|
||||
}
|
||||
|
@ -706,8 +706,11 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
VariableDeclaration variable = new VariableDeclaration.forValue(a);
|
||||
push(makeLet(
|
||||
variable,
|
||||
new ConditionalExpression(buildIsNull(new VariableGet(variable)), b,
|
||||
new VariableGet(variable), const DynamicType())));
|
||||
new ConditionalExpression(
|
||||
buildIsNull(astFactory, new VariableGet(variable)),
|
||||
b,
|
||||
new VariableGet(variable),
|
||||
const DynamicType())));
|
||||
}
|
||||
|
||||
/// Handle `a?.b(...)`.
|
||||
|
@ -751,7 +754,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
astFactory.directPropertyGet(new ThisExpression(), target);
|
||||
receiver = astFactory.superPropertyGet(node.name, target);
|
||||
return buildMethodInvocation(
|
||||
receiver, callName, node.arguments, node.fileOffset);
|
||||
astFactory, receiver, callName, node.arguments, node.fileOffset);
|
||||
}
|
||||
|
||||
bool areArgumentsCompatible(FunctionNode function, Arguments arguments) {
|
||||
|
@ -1743,13 +1746,14 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
}
|
||||
if (receiver is ThisAccessor && receiver.isSuper) {
|
||||
push(toSuperMethodInvocation(buildMethodInvocation(
|
||||
astFactory,
|
||||
astFactory.thisExpression(receiver.token),
|
||||
new Name(operator),
|
||||
new Arguments.empty(),
|
||||
token.charOffset)));
|
||||
} else {
|
||||
push(buildMethodInvocation(toValue(receiver), new Name(operator),
|
||||
new Arguments.empty(), token.charOffset));
|
||||
push(buildMethodInvocation(astFactory, toValue(receiver),
|
||||
new Name(operator), new Arguments.empty(), token.charOffset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,8 +128,8 @@ abstract class FastaAccessor implements Accessor {
|
|||
/* Expression | FastaAccessor */ buildPropertyAccess(
|
||||
IncompleteSend send, bool isNullAware) {
|
||||
if (send is SendAccessor) {
|
||||
return buildMethodInvocation(buildSimpleRead(), send.name, send.arguments,
|
||||
offsetForToken(send.token),
|
||||
return buildMethodInvocation(helper.astFactory, buildSimpleRead(),
|
||||
send.name, send.arguments, offsetForToken(send.token),
|
||||
isNullAware: isNullAware);
|
||||
} else {
|
||||
return PropertyAccessor.make(helper, send.token, buildSimpleRead(),
|
||||
|
@ -315,8 +315,12 @@ class ThisAccessor extends FastaAccessor {
|
|||
if (send is SendAccessor) {
|
||||
// Notice that 'this' or 'super' can't be null. So we can ignore the
|
||||
// value of [isNullAware].
|
||||
MethodInvocation result = buildMethodInvocation(new ThisExpression(),
|
||||
send.name, send.arguments, offsetForToken(token));
|
||||
MethodInvocation result = buildMethodInvocation(
|
||||
helper.astFactory,
|
||||
new ThisExpression(),
|
||||
send.name,
|
||||
send.arguments,
|
||||
offsetForToken(token));
|
||||
return isSuper ? helper.toSuperMethodInvocation(result) : result;
|
||||
} else {
|
||||
if (isSuper) {
|
||||
|
@ -336,7 +340,7 @@ class ThisAccessor extends FastaAccessor {
|
|||
return buildConstructorInitializer(offset, new Name(""), arguments);
|
||||
} else {
|
||||
return buildMethodInvocation(
|
||||
new ThisExpression(), callName, arguments, offset);
|
||||
helper.astFactory, new ThisExpression(), callName, arguments, offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -492,6 +496,7 @@ class SendAccessor extends IncompleteSend {
|
|||
if (target != null) {
|
||||
if (target is Field) {
|
||||
result = buildMethodInvocation(
|
||||
helper.astFactory,
|
||||
new StaticGet(target),
|
||||
callName,
|
||||
arguments,
|
||||
|
@ -507,7 +512,7 @@ class SendAccessor extends IncompleteSend {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
result = buildMethodInvocation(
|
||||
result = buildMethodInvocation(helper.astFactory,
|
||||
helper.toValue(receiver), name, arguments, offsetForToken(token),
|
||||
isNullAware: isNullAware);
|
||||
}
|
||||
|
@ -630,7 +635,7 @@ class IndexAccessor extends kernel.IndexAccessor with FastaAccessor {
|
|||
|
||||
IndexAccessor.internal(this.helper, Token token, Expression receiver,
|
||||
Expression index, Procedure getter, Procedure setter)
|
||||
: super.internal(receiver, index, getter, setter, token);
|
||||
: super.internal(helper, receiver, index, getter, setter, token);
|
||||
|
||||
String get plainNameForRead => "[]";
|
||||
|
||||
|
@ -638,7 +643,7 @@ class IndexAccessor extends kernel.IndexAccessor with FastaAccessor {
|
|||
|
||||
Expression doInvocation(int offset, Arguments arguments) {
|
||||
return buildMethodInvocation(
|
||||
buildSimpleRead(), callName, arguments, offset);
|
||||
helper.astFactory, buildSimpleRead(), callName, arguments, offset);
|
||||
}
|
||||
|
||||
toString() => "IndexAccessor()";
|
||||
|
@ -664,14 +669,15 @@ class PropertyAccessor extends kernel.PropertyAccessor with FastaAccessor {
|
|||
|
||||
PropertyAccessor.internal(this.helper, Token token, Expression receiver,
|
||||
Name name, Member getter, Member setter)
|
||||
: super.internal(receiver, name, getter, setter, token);
|
||||
: super.internal(helper, receiver, name, getter, setter, token);
|
||||
|
||||
String get plainNameForRead => name.name;
|
||||
|
||||
bool get isThisPropertyAccessor => receiver is ThisExpression;
|
||||
|
||||
Expression doInvocation(int offset, Arguments arguments) {
|
||||
return buildMethodInvocation(receiver, name, arguments, offset);
|
||||
return buildMethodInvocation(
|
||||
helper.astFactory, receiver, name, arguments, offset);
|
||||
}
|
||||
|
||||
toString() => "PropertyAccessor()";
|
||||
|
@ -728,8 +734,8 @@ class StaticAccessor extends kernel.StaticAccessor with FastaAccessor {
|
|||
|
||||
Expression doInvocation(int offset, Arguments arguments) {
|
||||
if (readTarget == null || isFieldOrGetter(readTarget)) {
|
||||
return buildMethodInvocation(buildSimpleRead(), callName, arguments,
|
||||
offset + (readTarget?.name?.name?.length ?? 0));
|
||||
return buildMethodInvocation(helper.astFactory, buildSimpleRead(),
|
||||
callName, arguments, offset + (readTarget?.name?.name?.length ?? 0));
|
||||
} else {
|
||||
return helper.buildStaticInvocation(readTarget, arguments)
|
||||
..fileOffset = offset;
|
||||
|
@ -741,18 +747,16 @@ class StaticAccessor extends kernel.StaticAccessor with FastaAccessor {
|
|||
|
||||
class SuperPropertyAccessor extends kernel.SuperPropertyAccessor
|
||||
with FastaAccessor {
|
||||
final BuilderHelper helper;
|
||||
|
||||
SuperPropertyAccessor(
|
||||
this.helper, Token token, Name name, Member getter, Member setter)
|
||||
: super(name, getter, setter, token);
|
||||
SuperPropertyAccessor(BuilderHelper helper, Token token, Name name,
|
||||
Member getter, Member setter)
|
||||
: super(helper, name, getter, setter, token);
|
||||
|
||||
String get plainNameForRead => name.name;
|
||||
|
||||
Expression doInvocation(int offset, Arguments arguments) {
|
||||
if (getter == null || isFieldOrGetter(getter)) {
|
||||
return buildMethodInvocation(
|
||||
buildSimpleRead(), callName, arguments, offset);
|
||||
helper.astFactory, buildSimpleRead(), callName, arguments, offset);
|
||||
} else {
|
||||
return new DirectMethodInvocation(new ThisExpression(), getter, arguments)
|
||||
..fileOffset = offset;
|
||||
|
@ -763,11 +767,9 @@ class SuperPropertyAccessor extends kernel.SuperPropertyAccessor
|
|||
}
|
||||
|
||||
class ThisIndexAccessor extends kernel.ThisIndexAccessor with FastaAccessor {
|
||||
final BuilderHelper helper;
|
||||
|
||||
ThisIndexAccessor(this.helper, Token token, Expression index,
|
||||
ThisIndexAccessor(BuilderHelper helper, Token token, Expression index,
|
||||
Procedure getter, Procedure setter)
|
||||
: super(index, getter, setter, token);
|
||||
: super(helper, index, getter, setter, token);
|
||||
|
||||
String get plainNameForRead => "[]";
|
||||
|
||||
|
@ -775,18 +777,16 @@ class ThisIndexAccessor extends kernel.ThisIndexAccessor with FastaAccessor {
|
|||
|
||||
Expression doInvocation(int offset, Arguments arguments) {
|
||||
return buildMethodInvocation(
|
||||
buildSimpleRead(), callName, arguments, offset);
|
||||
helper.astFactory, buildSimpleRead(), callName, arguments, offset);
|
||||
}
|
||||
|
||||
toString() => "ThisIndexAccessor()";
|
||||
}
|
||||
|
||||
class SuperIndexAccessor extends kernel.SuperIndexAccessor with FastaAccessor {
|
||||
final BuilderHelper helper;
|
||||
|
||||
SuperIndexAccessor(
|
||||
this.helper, Token token, Expression index, Member getter, Member setter)
|
||||
: super(index, getter, setter, token);
|
||||
SuperIndexAccessor(BuilderHelper helper, Token token, Expression index,
|
||||
Member getter, Member setter)
|
||||
: super(helper, index, getter, setter, token);
|
||||
|
||||
String get plainNameForRead => "[]";
|
||||
|
||||
|
@ -794,7 +794,7 @@ class SuperIndexAccessor extends kernel.SuperIndexAccessor with FastaAccessor {
|
|||
|
||||
Expression doInvocation(int offset, Arguments arguments) {
|
||||
return buildMethodInvocation(
|
||||
buildSimpleRead(), callName, arguments, offset);
|
||||
helper.astFactory, buildSimpleRead(), callName, arguments, offset);
|
||||
}
|
||||
|
||||
toString() => "SuperIndexAccessor()";
|
||||
|
@ -806,7 +806,7 @@ class ThisPropertyAccessor extends kernel.ThisPropertyAccessor
|
|||
|
||||
ThisPropertyAccessor(
|
||||
this.helper, Token token, Name name, Member getter, Member setter)
|
||||
: super(name, getter, setter, token);
|
||||
: super(helper, name, getter, setter, token);
|
||||
|
||||
String get plainNameForRead => name.name;
|
||||
|
||||
|
@ -819,7 +819,8 @@ class ThisPropertyAccessor extends kernel.ThisPropertyAccessor
|
|||
// `this.name.call(arguments)`.
|
||||
interfaceTarget = null;
|
||||
}
|
||||
return buildMethodInvocation(new ThisExpression(), name, arguments, offset);
|
||||
return buildMethodInvocation(
|
||||
helper.astFactory, new ThisExpression(), name, arguments, offset);
|
||||
}
|
||||
|
||||
toString() => "ThisPropertyAccessor()";
|
||||
|
@ -831,7 +832,7 @@ class NullAwarePropertyAccessor extends kernel.NullAwarePropertyAccessor
|
|||
|
||||
NullAwarePropertyAccessor(this.helper, Token token, Expression receiver,
|
||||
Name name, Member getter, Member setter, DartType type)
|
||||
: super(receiver, name, getter, setter, type, token);
|
||||
: super(helper, receiver, name, getter, setter, type, token);
|
||||
|
||||
String get plainNameForRead => name.name;
|
||||
|
||||
|
@ -843,37 +844,33 @@ class NullAwarePropertyAccessor extends kernel.NullAwarePropertyAccessor
|
|||
}
|
||||
|
||||
class VariableAccessor extends kernel.VariableAccessor with FastaAccessor {
|
||||
@override
|
||||
final BuilderHelper helper;
|
||||
|
||||
VariableAccessor(this.helper, Token token, VariableDeclaration variable,
|
||||
VariableAccessor(
|
||||
BuilderHelper helper, Token token, VariableDeclaration variable,
|
||||
[DartType promotedType])
|
||||
: super(variable, promotedType, token);
|
||||
: super(helper, variable, promotedType, token);
|
||||
|
||||
String get plainNameForRead => variable.name;
|
||||
|
||||
Expression doInvocation(int offset, Arguments arguments) {
|
||||
// Normally the offset is at the start of the token, but in this case,
|
||||
// because we insert a '.call', we want it at the end instead.
|
||||
return buildMethodInvocation(buildSimpleRead(), callName, arguments,
|
||||
offset + (variable.name?.length ?? 0));
|
||||
return buildMethodInvocation(helper.astFactory, buildSimpleRead(), callName,
|
||||
arguments, offset + (variable.name?.length ?? 0));
|
||||
}
|
||||
|
||||
toString() => "VariableAccessor()";
|
||||
}
|
||||
|
||||
class ReadOnlyAccessor extends kernel.ReadOnlyAccessor with FastaAccessor {
|
||||
final BuilderHelper helper;
|
||||
|
||||
final String plainNameForRead;
|
||||
|
||||
ReadOnlyAccessor(
|
||||
this.helper, Expression expression, this.plainNameForRead, Token token)
|
||||
: super(expression, token);
|
||||
ReadOnlyAccessor(BuilderHelper helper, Expression expression,
|
||||
this.plainNameForRead, Token token)
|
||||
: super(helper, expression, token);
|
||||
|
||||
Expression doInvocation(int offset, Arguments arguments) {
|
||||
return buildMethodInvocation(
|
||||
buildSimpleRead(), callName, arguments, offset);
|
||||
helper.astFactory, buildSimpleRead(), callName, arguments, offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -917,20 +914,22 @@ bool isFieldOrGetter(Member member) {
|
|||
return member is Field || (member is Procedure && member.isGetter);
|
||||
}
|
||||
|
||||
Expression buildMethodInvocation(
|
||||
Expression receiver, Name name, Arguments arguments, int offset,
|
||||
Expression buildMethodInvocation(AstFactory astFactory, Expression receiver,
|
||||
Name name, Arguments arguments, int offset,
|
||||
{bool isNullAware: false}) {
|
||||
if (isNullAware) {
|
||||
VariableDeclaration variable = new VariableDeclaration.forValue(receiver);
|
||||
return makeLet(
|
||||
variable,
|
||||
new ConditionalExpression(
|
||||
buildIsNull(new VariableGet(variable)),
|
||||
buildIsNull(astFactory, new VariableGet(variable)),
|
||||
new NullLiteral(),
|
||||
new MethodInvocation(new VariableGet(variable), name, arguments)
|
||||
astFactory.methodInvocation(
|
||||
new VariableGet(variable), name, arguments)
|
||||
..fileOffset = offset,
|
||||
const DynamicType()));
|
||||
} else {
|
||||
return new MethodInvocation(receiver, name, arguments)..fileOffset = offset;
|
||||
return astFactory.methodInvocation(receiver, name, arguments)
|
||||
..fileOffset = offset;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:front_end/src/fasta/builder/ast_factory.dart';
|
||||
|
||||
/// A library to help transform compounds and null-aware accessors into
|
||||
/// let expressions.
|
||||
|
||||
|
@ -12,7 +14,7 @@ import 'package:front_end/src/fasta/scanner/token.dart' show Token;
|
|||
import 'package:front_end/src/fasta/kernel/fasta_accessors.dart'
|
||||
show BuilderHelper;
|
||||
|
||||
import 'package:kernel/ast.dart';
|
||||
import 'package:kernel/ast.dart' hide MethodInvocation;
|
||||
|
||||
final Name indexGetName = new Name("[]");
|
||||
|
||||
|
@ -31,6 +33,7 @@ final Name indexSetName = new Name("[]=");
|
|||
/// [Accessor] object. Later, after `= b` is parsed, [buildAssignment] will be
|
||||
/// called.
|
||||
abstract class Accessor {
|
||||
final BuilderHelper helper;
|
||||
final Token token;
|
||||
|
||||
// [builtBinary] and [builtGetter] capture the inner nodes. Used by
|
||||
|
@ -40,7 +43,7 @@ abstract class Accessor {
|
|||
Expression builtBinary;
|
||||
Expression builtGetter;
|
||||
|
||||
Accessor(this.token);
|
||||
Accessor(this.helper, this.token);
|
||||
|
||||
/// Builds an [Expression] representing a read from the accessor.
|
||||
Expression buildSimpleRead() {
|
||||
|
@ -66,14 +69,20 @@ abstract class Accessor {
|
|||
Expression buildNullAwareAssignment(Expression value, DartType type,
|
||||
{bool voidContext: false}) {
|
||||
if (voidContext) {
|
||||
return _finish(new ConditionalExpression(buildIsNull(_makeRead()),
|
||||
_makeWrite(value, false), new NullLiteral(), type));
|
||||
return _finish(new ConditionalExpression(
|
||||
buildIsNull(helper.astFactory, _makeRead()),
|
||||
_makeWrite(value, false),
|
||||
new NullLiteral(),
|
||||
type));
|
||||
}
|
||||
var tmp = new VariableDeclaration.forValue(_makeRead());
|
||||
return _finish(makeLet(
|
||||
tmp,
|
||||
new ConditionalExpression(buildIsNull(new VariableGet(tmp)),
|
||||
_makeWrite(value, false), new VariableGet(tmp), type)));
|
||||
new ConditionalExpression(
|
||||
buildIsNull(helper.astFactory, new VariableGet(tmp)),
|
||||
_makeWrite(value, false),
|
||||
new VariableGet(tmp),
|
||||
type)));
|
||||
}
|
||||
|
||||
/// Returns an [Expression] representing a compound assignment (e.g. `+=`)
|
||||
|
@ -83,8 +92,8 @@ abstract class Accessor {
|
|||
bool voidContext: false,
|
||||
Procedure interfaceTarget}) {
|
||||
return _finish(_makeWrite(
|
||||
builtBinary = makeBinary(
|
||||
_makeRead(), binaryOperator, interfaceTarget, value,
|
||||
builtBinary = makeBinary(helper.astFactory, _makeRead(), binaryOperator,
|
||||
interfaceTarget, value,
|
||||
offset: offset),
|
||||
voidContext));
|
||||
}
|
||||
|
@ -114,8 +123,8 @@ abstract class Accessor {
|
|||
var value = new VariableDeclaration.forValue(_makeRead());
|
||||
valueAccess() => new VariableGet(value);
|
||||
var dummy = new VariableDeclaration.forValue(_makeWrite(
|
||||
builtBinary = makeBinary(
|
||||
valueAccess(), binaryOperator, interfaceTarget, new IntLiteral(1),
|
||||
builtBinary = makeBinary(helper.astFactory, valueAccess(),
|
||||
binaryOperator, interfaceTarget, new IntLiteral(1),
|
||||
offset: offset),
|
||||
true));
|
||||
return _finish(makeLet(value, makeLet(dummy, valueAccess())));
|
||||
|
@ -149,10 +158,9 @@ abstract class VariableAccessor extends Accessor {
|
|||
VariableDeclaration variable;
|
||||
DartType promotedType;
|
||||
|
||||
BuilderHelper get helper;
|
||||
|
||||
VariableAccessor(this.variable, this.promotedType, Token token)
|
||||
: super(token);
|
||||
VariableAccessor(
|
||||
BuilderHelper helper, this.variable, this.promotedType, Token token)
|
||||
: super(helper, token);
|
||||
|
||||
Expression _makeRead() {
|
||||
var fact = helper.typePromoter
|
||||
|
@ -176,26 +184,27 @@ class PropertyAccessor extends Accessor {
|
|||
Name name;
|
||||
Member getter, setter;
|
||||
|
||||
static Accessor make(
|
||||
Expression receiver, Name name, Member getter, Member setter,
|
||||
static Accessor make(BuilderHelper helper, Expression receiver, Name name,
|
||||
Member getter, Member setter,
|
||||
{Token token}) {
|
||||
if (receiver is ThisExpression) {
|
||||
return new ThisPropertyAccessor(name, getter, setter, token);
|
||||
return new ThisPropertyAccessor(helper, name, getter, setter, token);
|
||||
} else {
|
||||
return new PropertyAccessor.internal(
|
||||
receiver, name, getter, setter, token);
|
||||
helper, receiver, name, getter, setter, token);
|
||||
}
|
||||
}
|
||||
|
||||
PropertyAccessor.internal(
|
||||
this.receiver, this.name, this.getter, this.setter, Token token)
|
||||
: super(token);
|
||||
PropertyAccessor.internal(BuilderHelper helper, this.receiver, this.name,
|
||||
this.getter, this.setter, Token token)
|
||||
: super(helper, token);
|
||||
|
||||
Expression _makeSimpleRead() => new PropertyGet(receiver, name, getter)
|
||||
..fileOffset = offsetForToken(token);
|
||||
Expression _makeSimpleRead() =>
|
||||
helper.astFactory.propertyGet(receiver, name, getter)
|
||||
..fileOffset = offsetForToken(token);
|
||||
|
||||
Expression _makeSimpleWrite(Expression value, bool voidContext) {
|
||||
return new PropertySet(receiver, name, value, setter)
|
||||
return helper.astFactory.propertySet(receiver, name, value, setter)
|
||||
..fileOffset = offsetForToken(token);
|
||||
}
|
||||
|
||||
|
@ -205,12 +214,12 @@ class PropertyAccessor extends Accessor {
|
|||
..fileOffset = offsetForToken(token);
|
||||
}
|
||||
|
||||
Expression _makeRead() =>
|
||||
builtGetter = new PropertyGet(receiverAccess(), name, getter)
|
||||
Expression _makeRead() => builtGetter = helper.astFactory
|
||||
.propertyGet(receiverAccess(), name, getter)
|
||||
..fileOffset = offsetForToken(token);
|
||||
|
||||
Expression _makeWrite(Expression value, bool voidContext) {
|
||||
return new PropertySet(receiverAccess(), name, value, setter)
|
||||
return helper.astFactory.propertySet(receiverAccess(), name, value, setter)
|
||||
..fileOffset = offsetForToken(token);
|
||||
}
|
||||
|
||||
|
@ -223,16 +232,18 @@ class ThisPropertyAccessor extends Accessor {
|
|||
Name name;
|
||||
Member getter, setter;
|
||||
|
||||
ThisPropertyAccessor(this.name, this.getter, this.setter, Token token)
|
||||
: super(token);
|
||||
ThisPropertyAccessor(
|
||||
BuilderHelper helper, this.name, this.getter, this.setter, Token token)
|
||||
: super(helper, token);
|
||||
|
||||
Expression _makeRead() =>
|
||||
builtGetter = new PropertyGet(new ThisExpression(), name, getter)
|
||||
Expression _makeRead() => builtGetter = helper.astFactory
|
||||
.propertyGet(new ThisExpression(), name, getter)
|
||||
..fileOffset = offsetForToken(token);
|
||||
|
||||
Expression _makeWrite(Expression value, bool voidContext) {
|
||||
return new PropertySet(new ThisExpression(), name, value, setter)
|
||||
..fileOffset = offsetForToken(token);
|
||||
return helper.astFactory
|
||||
.propertySet(new ThisExpression(), name, value, setter)
|
||||
..fileOffset = offsetForToken(token);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,32 +253,36 @@ class NullAwarePropertyAccessor extends Accessor {
|
|||
Member getter, setter;
|
||||
DartType type;
|
||||
|
||||
NullAwarePropertyAccessor(Expression receiver, this.name, this.getter,
|
||||
this.setter, this.type, Token token)
|
||||
NullAwarePropertyAccessor(BuilderHelper helper, Expression receiver,
|
||||
this.name, this.getter, this.setter, this.type, Token token)
|
||||
: this.receiver = makeOrReuseVariable(receiver),
|
||||
super(token);
|
||||
super(helper, token);
|
||||
|
||||
receiverAccess() => new VariableGet(receiver);
|
||||
|
||||
Expression _makeRead() =>
|
||||
builtGetter = new PropertyGet(receiverAccess(), name, getter);
|
||||
Expression _makeRead() => builtGetter =
|
||||
helper.astFactory.propertyGet(receiverAccess(), name, getter);
|
||||
|
||||
Expression _makeWrite(Expression value, bool voidContext) {
|
||||
return new PropertySet(receiverAccess(), name, value, setter);
|
||||
return helper.astFactory.propertySet(receiverAccess(), name, value, setter);
|
||||
}
|
||||
|
||||
Expression _finish(Expression body) => makeLet(
|
||||
receiver,
|
||||
new ConditionalExpression(
|
||||
buildIsNull(receiverAccess()), new NullLiteral(), body, type));
|
||||
buildIsNull(helper.astFactory, receiverAccess()),
|
||||
new NullLiteral(),
|
||||
body,
|
||||
type));
|
||||
}
|
||||
|
||||
class SuperPropertyAccessor extends Accessor {
|
||||
Name name;
|
||||
Member getter, setter;
|
||||
|
||||
SuperPropertyAccessor(this.name, this.getter, this.setter, Token token)
|
||||
: super(token);
|
||||
SuperPropertyAccessor(
|
||||
BuilderHelper helper, this.name, this.getter, this.setter, Token token)
|
||||
: super(helper, token);
|
||||
|
||||
Expression _makeRead() {
|
||||
if (getter == null) return makeInvalidRead();
|
||||
|
@ -291,27 +306,28 @@ class IndexAccessor extends Accessor {
|
|||
VariableDeclaration indexVariable;
|
||||
Procedure getter, setter;
|
||||
|
||||
static Accessor make(
|
||||
Expression receiver, Expression index, Procedure getter, Procedure setter,
|
||||
static Accessor make(BuilderHelper helper, Expression receiver,
|
||||
Expression index, Procedure getter, Procedure setter,
|
||||
{Token token}) {
|
||||
if (receiver is ThisExpression) {
|
||||
return new ThisIndexAccessor(index, getter, setter, token);
|
||||
return new ThisIndexAccessor(helper, index, getter, setter, token);
|
||||
} else {
|
||||
return new IndexAccessor.internal(receiver, index, getter, setter, token);
|
||||
return new IndexAccessor.internal(
|
||||
helper, receiver, index, getter, setter, token);
|
||||
}
|
||||
}
|
||||
|
||||
IndexAccessor.internal(
|
||||
this.receiver, this.index, this.getter, this.setter, Token token)
|
||||
: super(token);
|
||||
IndexAccessor.internal(BuilderHelper helper, this.receiver, this.index,
|
||||
this.getter, this.setter, Token token)
|
||||
: super(helper, token);
|
||||
|
||||
Expression _makeSimpleRead() => new MethodInvocation(
|
||||
Expression _makeSimpleRead() => helper.astFactory.methodInvocation(
|
||||
receiver, indexGetName, new Arguments(<Expression>[index]), getter)
|
||||
..fileOffset = offsetForToken(token);
|
||||
|
||||
Expression _makeSimpleWrite(Expression value, bool voidContext) {
|
||||
if (!voidContext) return _makeWriteAndReturn(value);
|
||||
return new MethodInvocation(receiver, indexSetName,
|
||||
return helper.astFactory.methodInvocation(receiver, indexSetName,
|
||||
new Arguments(<Expression>[index, value]), setter)
|
||||
..fileOffset = offsetForToken(token);
|
||||
}
|
||||
|
@ -330,14 +346,14 @@ class IndexAccessor extends Accessor {
|
|||
}
|
||||
|
||||
Expression _makeRead() {
|
||||
return builtGetter = new MethodInvocation(receiverAccess(), indexGetName,
|
||||
new Arguments(<Expression>[indexAccess()]), getter)
|
||||
return builtGetter = helper.astFactory.methodInvocation(receiverAccess(),
|
||||
indexGetName, new Arguments(<Expression>[indexAccess()]), getter)
|
||||
..fileOffset = offsetForToken(token);
|
||||
}
|
||||
|
||||
Expression _makeWrite(Expression value, bool voidContext) {
|
||||
if (!voidContext) return _makeWriteAndReturn(value);
|
||||
return new MethodInvocation(receiverAccess(), indexSetName,
|
||||
return helper.astFactory.methodInvocation(receiverAccess(), indexSetName,
|
||||
new Arguments(<Expression>[indexAccess(), value]), setter)
|
||||
..fileOffset = offsetForToken(token);
|
||||
}
|
||||
|
@ -348,13 +364,14 @@ class IndexAccessor extends Accessor {
|
|||
// 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 dummy = new VariableDeclaration.forValue(new MethodInvocation(
|
||||
receiverAccess(),
|
||||
indexSetName,
|
||||
new Arguments(
|
||||
<Expression>[indexAccess(), new VariableGet(valueVariable)]),
|
||||
setter)
|
||||
..fileOffset = offsetForToken(token));
|
||||
var dummy = new VariableDeclaration.forValue(helper.astFactory
|
||||
.methodInvocation(
|
||||
receiverAccess(),
|
||||
indexSetName,
|
||||
new Arguments(
|
||||
<Expression>[indexAccess(), new VariableGet(valueVariable)]),
|
||||
setter)
|
||||
..fileOffset = offsetForToken(token));
|
||||
return makeLet(
|
||||
valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
|
||||
}
|
||||
|
@ -371,18 +388,19 @@ class ThisIndexAccessor extends Accessor {
|
|||
VariableDeclaration indexVariable;
|
||||
Procedure getter, setter;
|
||||
|
||||
ThisIndexAccessor(this.index, this.getter, this.setter, Token token)
|
||||
: super(token);
|
||||
ThisIndexAccessor(
|
||||
BuilderHelper helper, this.index, this.getter, this.setter, Token token)
|
||||
: super(helper, token);
|
||||
|
||||
Expression _makeSimpleRead() {
|
||||
return new MethodInvocation(new ThisExpression(), indexGetName,
|
||||
new Arguments(<Expression>[index]), getter);
|
||||
return helper.astFactory.methodInvocation(new ThisExpression(),
|
||||
indexGetName, new Arguments(<Expression>[index]), getter);
|
||||
}
|
||||
|
||||
Expression _makeSimpleWrite(Expression value, bool voidContext) {
|
||||
if (!voidContext) return _makeWriteAndReturn(value);
|
||||
return new MethodInvocation(new ThisExpression(), indexSetName,
|
||||
new Arguments(<Expression>[index, value]), setter);
|
||||
return helper.astFactory.methodInvocation(new ThisExpression(),
|
||||
indexSetName, new Arguments(<Expression>[index, value]), setter);
|
||||
}
|
||||
|
||||
indexAccess() {
|
||||
|
@ -390,7 +408,7 @@ class ThisIndexAccessor extends Accessor {
|
|||
return new VariableGet(indexVariable);
|
||||
}
|
||||
|
||||
Expression _makeRead() => builtGetter = new MethodInvocation(
|
||||
Expression _makeRead() => builtGetter = helper.astFactory.methodInvocation(
|
||||
new ThisExpression(),
|
||||
indexGetName,
|
||||
new Arguments(<Expression>[indexAccess()]),
|
||||
|
@ -398,18 +416,22 @@ class ThisIndexAccessor extends Accessor {
|
|||
|
||||
Expression _makeWrite(Expression value, bool voidContext) {
|
||||
if (!voidContext) return _makeWriteAndReturn(value);
|
||||
return new MethodInvocation(new ThisExpression(), indexSetName,
|
||||
new Arguments(<Expression>[indexAccess(), value]), setter);
|
||||
return helper.astFactory.methodInvocation(
|
||||
new ThisExpression(),
|
||||
indexSetName,
|
||||
new Arguments(<Expression>[indexAccess(), value]),
|
||||
setter);
|
||||
}
|
||||
|
||||
_makeWriteAndReturn(Expression value) {
|
||||
var valueVariable = new VariableDeclaration.forValue(value);
|
||||
var dummy = new VariableDeclaration.forValue(new MethodInvocation(
|
||||
new ThisExpression(),
|
||||
indexSetName,
|
||||
new Arguments(
|
||||
<Expression>[indexAccess(), new VariableGet(valueVariable)]),
|
||||
setter));
|
||||
var dummy = new VariableDeclaration.forValue(helper.astFactory
|
||||
.methodInvocation(
|
||||
new ThisExpression(),
|
||||
indexSetName,
|
||||
new Arguments(
|
||||
<Expression>[indexAccess(), new VariableGet(valueVariable)]),
|
||||
setter));
|
||||
return makeLet(
|
||||
valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
|
||||
}
|
||||
|
@ -422,8 +444,9 @@ class SuperIndexAccessor extends Accessor {
|
|||
VariableDeclaration indexVariable;
|
||||
Member getter, setter;
|
||||
|
||||
SuperIndexAccessor(this.index, this.getter, this.setter, Token token)
|
||||
: super(token);
|
||||
SuperIndexAccessor(
|
||||
BuilderHelper helper, this.index, this.getter, this.setter, Token token)
|
||||
: super(helper, token);
|
||||
|
||||
indexAccess() {
|
||||
indexVariable ??= new VariableDeclaration.forValue(index);
|
||||
|
@ -467,12 +490,12 @@ class SuperIndexAccessor extends Accessor {
|
|||
}
|
||||
|
||||
class StaticAccessor extends Accessor {
|
||||
final BuilderHelper helper;
|
||||
Member readTarget;
|
||||
Member writeTarget;
|
||||
|
||||
StaticAccessor(this.helper, this.readTarget, this.writeTarget, Token token)
|
||||
: super(token);
|
||||
StaticAccessor(
|
||||
BuilderHelper helper, this.readTarget, this.writeTarget, Token token)
|
||||
: super(helper, token);
|
||||
|
||||
Expression _makeRead() => builtGetter = readTarget == null
|
||||
? makeInvalidRead()
|
||||
|
@ -490,7 +513,8 @@ class ReadOnlyAccessor extends Accessor {
|
|||
Expression expression;
|
||||
VariableDeclaration value;
|
||||
|
||||
ReadOnlyAccessor(this.expression, Token token) : super(token);
|
||||
ReadOnlyAccessor(BuilderHelper helper, this.expression, Token token)
|
||||
: super(helper, token);
|
||||
|
||||
Expression _makeSimpleRead() => expression;
|
||||
|
||||
|
@ -510,18 +534,19 @@ Expression makeLet(VariableDeclaration variable, Expression body) {
|
|||
return new Let(variable, body);
|
||||
}
|
||||
|
||||
Expression makeBinary(
|
||||
Expression left, Name operator, Procedure interfaceTarget, Expression right,
|
||||
Expression makeBinary(AstFactory astFactory, Expression left, Name operator,
|
||||
Procedure interfaceTarget, Expression right,
|
||||
{int offset: TreeNode.noOffset}) {
|
||||
return new MethodInvocation(
|
||||
return astFactory.methodInvocation(
|
||||
left, operator, new Arguments(<Expression>[right]), interfaceTarget)
|
||||
..fileOffset = offset;
|
||||
}
|
||||
|
||||
final Name _equalOperator = new Name('==');
|
||||
|
||||
Expression buildIsNull(Expression value, {int offset: TreeNode.noOffset}) {
|
||||
return makeBinary(value, _equalOperator, null, new NullLiteral(),
|
||||
Expression buildIsNull(AstFactory astFactory, Expression value,
|
||||
{int offset: TreeNode.noOffset}) {
|
||||
return makeBinary(astFactory, value, _equalOperator, null, new NullLiteral(),
|
||||
offset: offset);
|
||||
}
|
||||
|
||||
|
|
|
@ -127,6 +127,13 @@ class KernelAstFactory implements AstFactory<VariableDeclaration> {
|
|||
..fileOffset = constKeyword?.charOffset ?? beginToken.charOffset;
|
||||
}
|
||||
|
||||
@override
|
||||
MethodInvocation methodInvocation(
|
||||
Expression receiver, Name name, Arguments arguments,
|
||||
[Procedure interfaceTarget]) {
|
||||
return new KernelMethodInvocation(receiver, name, arguments);
|
||||
}
|
||||
|
||||
@override
|
||||
Not not(Token token, Expression operand) {
|
||||
return new KernelNot(operand)..fileOffset = offsetForToken(token);
|
||||
|
@ -137,6 +144,18 @@ class KernelAstFactory implements AstFactory<VariableDeclaration> {
|
|||
return new KernelNullLiteral()..fileOffset = offsetForToken(token);
|
||||
}
|
||||
|
||||
@override
|
||||
PropertyGet propertyGet(Expression receiver, Name name,
|
||||
[Member interfaceTarget]) {
|
||||
return new KernelPropertyGet(receiver, name, interfaceTarget);
|
||||
}
|
||||
|
||||
@override
|
||||
PropertySet propertySet(Expression receiver, Name name, Expression value,
|
||||
[Member interfaceTarget]) {
|
||||
return new KernelPropertySet(receiver, name, value, interfaceTarget);
|
||||
}
|
||||
|
||||
@override
|
||||
Rethrow rethrowExpression(Token keyword) {
|
||||
return new KernelRethrow()..fileOffset = offsetForToken(keyword);
|
||||
|
|
|
@ -345,8 +345,9 @@ class KernelMapLiteral extends MapLiteral implements KernelExpression {
|
|||
/// Shadow object for [MethodInvocation].
|
||||
class KernelMethodInvocation extends MethodInvocation
|
||||
implements KernelExpression {
|
||||
KernelMethodInvocation(Expression receiver, Name name, Arguments arguments)
|
||||
: super(receiver, name, arguments);
|
||||
KernelMethodInvocation(Expression receiver, Name name, Arguments arguments,
|
||||
[Procedure interfaceTarget])
|
||||
: super(receiver, name, arguments, interfaceTarget);
|
||||
|
||||
KernelMethodInvocation.byReference(Expression receiver, Name name,
|
||||
Arguments arguments, Reference interfaceTargetReference)
|
||||
|
@ -384,7 +385,8 @@ class KernelNullLiteral extends NullLiteral implements KernelExpression {
|
|||
|
||||
/// Shadow object for [PropertyGet].
|
||||
class KernelPropertyGet extends PropertyGet implements KernelExpression {
|
||||
KernelPropertyGet(Expression receiver, Name name) : super(receiver, name);
|
||||
KernelPropertyGet(Expression receiver, Name name, [Member interfaceTarget])
|
||||
: super(receiver, name, interfaceTarget);
|
||||
|
||||
KernelPropertyGet.byReference(
|
||||
Expression receiver, Name name, Reference interfaceTargetReference)
|
||||
|
@ -400,8 +402,9 @@ class KernelPropertyGet extends PropertyGet implements KernelExpression {
|
|||
|
||||
/// Shadow object for [PropertyGet].
|
||||
class KernelPropertySet extends PropertySet implements KernelExpression {
|
||||
KernelPropertySet(Expression receiver, Name name, Expression value)
|
||||
: super(receiver, name, value);
|
||||
KernelPropertySet(Expression receiver, Name name, Expression value,
|
||||
[Member interfaceTarget])
|
||||
: super(receiver, name, value, interfaceTarget);
|
||||
|
||||
KernelPropertySet.byReference(Expression receiver, Name name,
|
||||
Expression value, Reference interfaceTargetReference)
|
||||
|
|
Loading…
Reference in a new issue