mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 11:58:13 +00:00
Remove FastaAccessor and Accessor
Change-Id: I439670b0fafa09536901647572615afa4e82977a Reviewed-on: https://dart-review.googlesource.com/55965 Commit-Queue: Peter von der Ahé <ahe@google.com> Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
parent
a738567968
commit
09582b46ea
|
@ -88,7 +88,6 @@ import 'expression_generator.dart'
|
|||
CalleeDesignation,
|
||||
DeferredAccessGenerator,
|
||||
ErroneousExpressionGenerator,
|
||||
FastaAccessor,
|
||||
FunctionTypeAccessor,
|
||||
Generator,
|
||||
IncompleteError,
|
||||
|
@ -274,7 +273,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
|
||||
@override
|
||||
Expression toValue(Object node) {
|
||||
if (node is FastaAccessor) {
|
||||
if (node is Generator) {
|
||||
return toExpression(node.buildSimpleRead());
|
||||
} else if (node is Expression) {
|
||||
return node;
|
||||
|
@ -292,7 +291,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
}
|
||||
|
||||
Expression toEffect(Object node) {
|
||||
if (node is FastaAccessor) return toExpression(node.buildForEffect());
|
||||
if (node is Generator) return toExpression(node.buildForEffect());
|
||||
return toValue(node);
|
||||
}
|
||||
|
||||
|
@ -442,8 +441,8 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
}
|
||||
if (name?.isNotEmpty ?? false) {
|
||||
Token period = periodBeforeName ?? beginToken.next;
|
||||
FastaAccessor accessor = expression;
|
||||
expression = accessor.buildPropertyAccess(
|
||||
Generator generator = expression;
|
||||
expression = generator.buildPropertyAccess(
|
||||
new IncompletePropertyAccessor(
|
||||
this, period.next, new Name(name, library.library)),
|
||||
period.next.offset,
|
||||
|
@ -620,7 +619,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
Initializer initializer;
|
||||
if (node is Initializer) {
|
||||
initializer = node;
|
||||
} else if (node is FastaAccessor) {
|
||||
} else if (node is Generator) {
|
||||
initializer = node.buildFieldInitializer(initializedFields);
|
||||
} else if (node is ConstructorInvocation) {
|
||||
initializer = buildSuperInitializer(
|
||||
|
@ -941,7 +940,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
|
||||
@override
|
||||
finishSend(Object receiver, Arguments arguments, int charOffset) {
|
||||
if (receiver is FastaAccessor) {
|
||||
if (receiver is Generator) {
|
||||
return receiver.doInvocation(charOffset, arguments);
|
||||
} else {
|
||||
return buildMethodInvocation(
|
||||
|
@ -1396,11 +1395,11 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
deprecated_addCompileTimeError(
|
||||
charOffset, "Not a constant expression.");
|
||||
}
|
||||
TypeDeclarationAccessor accessor = new TypeDeclarationAccessor(
|
||||
TypeDeclarationAccessor generator = new TypeDeclarationAccessor(
|
||||
this, token, prefix, charOffset, builder, name);
|
||||
return (prefix?.deferred == true)
|
||||
? new DeferredAccessGenerator(this, token, prefix, accessor)
|
||||
: accessor;
|
||||
? new DeferredAccessGenerator(this, token, prefix, generator)
|
||||
: generator;
|
||||
} else if (builder.isLocal) {
|
||||
if (constantContext != ConstantContext.none &&
|
||||
!builder.isConst &&
|
||||
|
@ -1449,11 +1448,11 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
return new ThisPropertyAccessGenerator(this, token, n, getter, setter);
|
||||
} else if (builder.isRegularMethod) {
|
||||
assert(builder.isStatic || builder.isTopLevel);
|
||||
StaticAccessGenerator accessor =
|
||||
StaticAccessGenerator generator =
|
||||
new StaticAccessGenerator(this, token, builder.target, null);
|
||||
return (prefix?.deferred == true)
|
||||
? new DeferredAccessGenerator(this, token, prefix, accessor)
|
||||
: accessor;
|
||||
? new DeferredAccessGenerator(this, token, prefix, generator)
|
||||
: generator;
|
||||
} else if (builder is PrefixBuilder) {
|
||||
if (constantContext != ConstantContext.none && builder.deferred) {
|
||||
deprecated_addCompileTimeError(
|
||||
|
@ -1477,10 +1476,10 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
} else if (builder.isField && !builder.isFinal) {
|
||||
setter = builder;
|
||||
}
|
||||
StaticAccessGenerator accessor =
|
||||
StaticAccessGenerator generator =
|
||||
new StaticAccessGenerator.fromBuilder(this, builder, token, setter);
|
||||
if (constantContext != ConstantContext.none) {
|
||||
Member readTarget = accessor.readTarget;
|
||||
Member readTarget = generator.readTarget;
|
||||
if (!(readTarget is Field && readTarget.isConst ||
|
||||
// Static tear-offs are also compile time constants.
|
||||
readTarget is Procedure)) {
|
||||
|
@ -1489,8 +1488,8 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
}
|
||||
}
|
||||
return (prefix?.deferred == true)
|
||||
? new DeferredAccessGenerator(this, token, prefix, accessor)
|
||||
: accessor;
|
||||
? new DeferredAccessGenerator(this, token, prefix, generator)
|
||||
: generator;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1789,13 +1788,13 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
void handleAssignmentExpression(Token token) {
|
||||
debugEvent("AssignmentExpression");
|
||||
Expression value = popForValue();
|
||||
var accessor = pop();
|
||||
if (accessor is! FastaAccessor) {
|
||||
var generator = pop();
|
||||
if (generator is! Generator) {
|
||||
push(buildCompileTimeError(fasta.messageNotAnLvalue,
|
||||
offsetForToken(token), lengthForToken(token)));
|
||||
} else {
|
||||
push(new DelayedAssignment(
|
||||
this, token, accessor, toKernelExpression(value), token.stringValue));
|
||||
push(new DelayedAssignment(this, token, generator,
|
||||
toKernelExpression(value), token.stringValue));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1821,7 +1820,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
}
|
||||
|
||||
List<VariableDeclaration> buildVariableDeclarations(variableOrExpression) {
|
||||
if (variableOrExpression is FastaAccessor) {
|
||||
if (variableOrExpression is Generator) {
|
||||
variableOrExpression = variableOrExpression.buildForEffect();
|
||||
}
|
||||
if (variableOrExpression is VariableDeclaration) {
|
||||
|
@ -2054,7 +2053,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (name is FastaAccessor) {
|
||||
if (name is Generator) {
|
||||
push(name.buildTypeWithBuiltArguments(arguments));
|
||||
} else if (name is TypeBuilder) {
|
||||
push(name.build(library));
|
||||
|
@ -2484,24 +2483,26 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
@override
|
||||
void handleUnaryPrefixAssignmentExpression(Token token) {
|
||||
debugEvent("UnaryPrefixAssignmentExpression");
|
||||
var accessor = pop();
|
||||
if (accessor is FastaAccessor) {
|
||||
push(accessor.buildPrefixIncrement(incrementOperator(token),
|
||||
var generator = pop();
|
||||
if (generator is Generator) {
|
||||
push(generator.buildPrefixIncrement(incrementOperator(token),
|
||||
offset: token.charOffset));
|
||||
} else {
|
||||
push(wrapInCompileTimeError(toValue(accessor), fasta.messageNotAnLvalue));
|
||||
push(
|
||||
wrapInCompileTimeError(toValue(generator), fasta.messageNotAnLvalue));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void handleUnaryPostfixAssignmentExpression(Token token) {
|
||||
debugEvent("UnaryPostfixAssignmentExpression");
|
||||
var accessor = pop();
|
||||
if (accessor is FastaAccessor) {
|
||||
var generator = pop();
|
||||
if (generator is Generator) {
|
||||
push(new DelayedPostfixIncrement<Arguments>(
|
||||
this, token, accessor, incrementOperator(token), null));
|
||||
this, token, generator, incrementOperator(token), null));
|
||||
} else {
|
||||
push(wrapInCompileTimeError(toValue(accessor), fasta.messageNotAnLvalue));
|
||||
push(
|
||||
wrapInCompileTimeError(toValue(generator), fasta.messageNotAnLvalue));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2542,7 +2543,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
/// But the parser can't tell this from type c) above.
|
||||
///
|
||||
/// This method pops 2 (or 3 if `periodBeforeName != null`) values from the
|
||||
/// stack and pushes 3 values: an accessor (the type in a constructor
|
||||
/// stack and pushes 3 values: a generator (the type in a constructor
|
||||
/// reference, or an expression in metadata), a list of type arguments, and a
|
||||
/// name.
|
||||
void pushQualifiedReference(Token start, Token periodBeforeName) {
|
||||
|
@ -2560,7 +2561,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
identifier = null;
|
||||
} else if (prefix is TypeDeclarationAccessor) {
|
||||
type = prefix;
|
||||
} else if (prefix is FastaAccessor) {
|
||||
} else if (prefix is Generator) {
|
||||
String name = suffix == null
|
||||
? "${prefix.plainNameForRead}.${identifier.name}"
|
||||
: "${prefix.plainNameForRead}.${identifier.name}.$suffix";
|
||||
|
@ -2787,18 +2788,18 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
PrefixBuilder deferredPrefix;
|
||||
int checkOffset;
|
||||
if (type is DeferredAccessGenerator) {
|
||||
DeferredAccessGenerator accessor = type;
|
||||
type = accessor.accessor;
|
||||
deferredPrefix = accessor.builder;
|
||||
checkOffset = accessor.token.charOffset;
|
||||
DeferredAccessGenerator generator = type;
|
||||
type = generator.generator;
|
||||
deferredPrefix = generator.builder;
|
||||
checkOffset = generator.token.charOffset;
|
||||
}
|
||||
|
||||
if (type is TypeDeclarationAccessor) {
|
||||
TypeDeclarationAccessor accessor = type;
|
||||
if (accessor.prefix != null) {
|
||||
TypeDeclarationAccessor generator = type;
|
||||
if (generator.prefix != null) {
|
||||
nameToken = nameToken.next.next;
|
||||
}
|
||||
type = accessor.declaration;
|
||||
type = generator.declaration;
|
||||
}
|
||||
|
||||
ConstantContext savedConstantContext = pop();
|
||||
|
@ -3205,7 +3206,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
deprecated_addCompileTimeError(
|
||||
variable.fileOffset, "A for-in loop-variable can't be 'const'.");
|
||||
}
|
||||
} else if (lvalue is FastaAccessor) {
|
||||
} else if (lvalue is Generator) {
|
||||
/// We are in this case, where `lvalue` isn't a [VariableDeclaration]:
|
||||
///
|
||||
/// for (lvalue in expression) body
|
||||
|
@ -4688,7 +4689,7 @@ String getNodeName(Object node) {
|
|||
return node.fullNameForErrors;
|
||||
} else if (node is ThisAccessGenerator) {
|
||||
return node.isSuper ? "super" : "this";
|
||||
} else if (node is FastaAccessor) {
|
||||
} else if (node is Generator) {
|
||||
return node.plainNameForRead;
|
||||
} else {
|
||||
return unhandled("${node.runtimeType}", "getNodeName", -1, null);
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
// 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.
|
||||
|
||||
/// A library to help transform compounds and null-aware accessors into
|
||||
/// let expressions.
|
||||
/// A library to help generate expression.
|
||||
library fasta.expression_generator;
|
||||
|
||||
import '../../scanner/token.dart' show Token;
|
||||
|
@ -103,35 +102,44 @@ import 'kernel_builder.dart'
|
|||
|
||||
part 'expression_generator_impl.dart';
|
||||
|
||||
/// An [Accessor] represents a subexpression for which we can't yet build a
|
||||
/// kernel [kernel.Expression] because we don't yet know the context in which
|
||||
/// it is used.
|
||||
/// A generator represents a subexpression for which we can't yet build an
|
||||
/// expression because we don't yet know the context in which it's used.
|
||||
///
|
||||
/// Once the context is known, an [Accessor] can be converted into an
|
||||
/// [kernel.Expression] by calling a "build" method.
|
||||
/// Once the context is known, a generator can be converted into an expression
|
||||
/// by calling a `build` method.
|
||||
///
|
||||
/// For example, when building a kernel representation for `a[x] = b`, after
|
||||
/// parsing `a[x]` but before parsing `= b`, we don't yet know whether to
|
||||
/// generate an invocation of `operator[]` or `operator[]=`, so we generate an
|
||||
/// [Accessor] object. Later, after `= b` is parsed, [buildAssignment] will be
|
||||
/// called.
|
||||
// TODO(ahe): Move this into [Generator] when all uses have been updated.
|
||||
abstract class Accessor<Arguments> {
|
||||
/// generate an invocation of `operator[]` or `operator[]=`, so we create a
|
||||
/// [Generator] object. Later, after `= b` is parsed, [buildAssignment] will
|
||||
/// be called.
|
||||
abstract class Generator<Arguments> {
|
||||
final BuilderHelper<dynamic, dynamic, Arguments> helper;
|
||||
final Token token;
|
||||
|
||||
Accessor(this.helper, this.token);
|
||||
Generator(this.helper, this.token);
|
||||
|
||||
// TODO(ahe): Change type arguments.
|
||||
Forest<kernel.Expression, kernel.Statement, Token, Arguments> get forest =>
|
||||
helper.forest;
|
||||
|
||||
/// Builds an [kernel.Expression] representing a read from the accessor.
|
||||
String get plainNameForRead;
|
||||
|
||||
String get debugName;
|
||||
|
||||
Uri get uri => helper.uri;
|
||||
|
||||
String get plainNameForWrite => plainNameForRead;
|
||||
|
||||
bool get isInitializer => false;
|
||||
|
||||
/// Builds a [kernel.Expression] representing a read from the generator.
|
||||
kernel.Expression buildSimpleRead() {
|
||||
return _finish(_makeSimpleRead(), null);
|
||||
}
|
||||
|
||||
/// Builds an [kernel.Expression] representing an assignment with the
|
||||
/// accessor on the LHS and [value] on the RHS.
|
||||
/// Builds a [kernel.Expression] representing an assignment with the
|
||||
/// generator on the LHS and [value] on the RHS.
|
||||
///
|
||||
/// The returned expression evaluates to the assigned value, unless
|
||||
/// [voidContext] is true, in which case it may evaluate to anything.
|
||||
|
@ -142,8 +150,8 @@ abstract class Accessor<Arguments> {
|
|||
complexAssignment);
|
||||
}
|
||||
|
||||
/// Returns an [kernel.Expression] representing a null-aware assignment
|
||||
/// (`??=`) with the accessor on the LHS and [value] on the RHS.
|
||||
/// Returns a [kernel.Expression] representing a null-aware assignment
|
||||
/// (`??=`) with the generator on the LHS and [value] on the RHS.
|
||||
///
|
||||
/// The returned expression evaluates to the assigned value, unless
|
||||
/// [voidContext] is true, in which case it may evaluate to anything.
|
||||
|
@ -178,8 +186,8 @@ abstract class Accessor<Arguments> {
|
|||
return _finish(makeLet(tmp, nullAwareCombiner), complexAssignment);
|
||||
}
|
||||
|
||||
/// Returns an [kernel.Expression] representing a compound assignment
|
||||
/// (e.g. `+=`) with the accessor on the LHS and [value] on the RHS.
|
||||
/// Returns a [kernel.Expression] representing a compound assignment
|
||||
/// (e.g. `+=`) with the generator on the LHS and [value] on the RHS.
|
||||
kernel.Expression buildCompoundAssignment(
|
||||
Name binaryOperator, kernel.Expression value,
|
||||
{int offset: TreeNode.noOffset,
|
||||
|
@ -196,8 +204,8 @@ abstract class Accessor<Arguments> {
|
|||
complexAssignment);
|
||||
}
|
||||
|
||||
/// Returns an [kernel.Expression] representing a pre-increment or
|
||||
/// pre-decrement of the accessor.
|
||||
/// Returns a [kernel.Expression] representing a pre-increment or
|
||||
/// pre-decrement of the generator.
|
||||
kernel.Expression buildPrefixIncrement(Name binaryOperator,
|
||||
{int offset: TreeNode.noOffset,
|
||||
bool voidContext: false,
|
||||
|
@ -210,8 +218,8 @@ abstract class Accessor<Arguments> {
|
|||
isPreIncDec: true);
|
||||
}
|
||||
|
||||
/// Returns an [kernel.Expression] representing a post-increment or
|
||||
/// post-decrement of the accessor.
|
||||
/// Returns a [kernel.Expression] representing a post-increment or
|
||||
/// post-decrement of the generator.
|
||||
kernel.Expression buildPostfixIncrement(Name binaryOperator,
|
||||
{int offset: TreeNode.noOffset,
|
||||
bool voidContext: false,
|
||||
|
@ -258,32 +266,103 @@ abstract class Accessor<Arguments> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns an [kernel.Expression] representing a compile-time error.
|
||||
/// Returns a [kernel.Expression] representing a compile-time error.
|
||||
///
|
||||
/// At runtime, an exception will be thrown.
|
||||
makeInvalidRead() {
|
||||
return unhandled("compile-time error", "$runtimeType",
|
||||
offsetForToken(token), helper.uri);
|
||||
kernel.Expression makeInvalidRead() {
|
||||
return buildThrowNoSuchMethodError(
|
||||
forest.literalNull(token), forest.argumentsEmpty(noLocation),
|
||||
isGetter: true);
|
||||
}
|
||||
|
||||
/// Returns an [kernel.Expression] representing a compile-time error wrapping
|
||||
/// Returns a [kernel.Expression] representing a compile-time error wrapping
|
||||
/// [value].
|
||||
///
|
||||
/// At runtime, [value] will be evaluated before throwing an exception.
|
||||
makeInvalidWrite(kernel.Expression value) {
|
||||
return unhandled("compile-time error", "$runtimeType",
|
||||
offsetForToken(token), helper.uri);
|
||||
kernel.Expression makeInvalidWrite(kernel.Expression value) {
|
||||
return buildThrowNoSuchMethodError(forest.literalNull(token),
|
||||
forest.arguments(<kernel.Expression>[value], noLocation),
|
||||
isSetter: true);
|
||||
}
|
||||
|
||||
/// Creates a data structure for tracking the desugaring of a complex
|
||||
/// assignment expression whose right hand side is [rhs].
|
||||
ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
|
||||
new ShadowIllegalAssignment(rhs);
|
||||
}
|
||||
|
||||
// TODO(ahe): Merge classes [Accessor] and [FastaAccessor] into this.
|
||||
abstract class Generator<Arguments> = Accessor<Arguments>
|
||||
with FastaAccessor<Arguments>;
|
||||
T storeOffset<T>(T node, int offset) {
|
||||
return helper.storeOffset(node, offset);
|
||||
}
|
||||
|
||||
kernel.Expression buildForEffect() => buildSimpleRead();
|
||||
|
||||
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
|
||||
int offset = offsetForToken(token);
|
||||
return helper.buildInvalidInitializer(
|
||||
helper.buildCompileTimeError(
|
||||
messageInvalidInitializer, offset, lengthForToken(token)),
|
||||
offset);
|
||||
}
|
||||
|
||||
/* kernel.Expression | Generator | Initializer */ doInvocation(
|
||||
int offset, Arguments arguments);
|
||||
|
||||
/* kernel.Expression | Generator */ buildPropertyAccess(
|
||||
IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
|
||||
if (send is SendAccessor) {
|
||||
return helper.buildMethodInvocation(buildSimpleRead(), send.name,
|
||||
send.arguments, offsetForToken(send.token),
|
||||
isNullAware: isNullAware);
|
||||
} else {
|
||||
if (helper.constantContext != ConstantContext.none &&
|
||||
send.name != lengthName) {
|
||||
helper.deprecated_addCompileTimeError(
|
||||
offsetForToken(token), "Not a constant expression.");
|
||||
}
|
||||
return PropertyAccessGenerator.make(helper, send.token, buildSimpleRead(),
|
||||
send.name, null, null, isNullAware);
|
||||
}
|
||||
}
|
||||
|
||||
DartType buildTypeWithBuiltArguments(List<DartType> arguments,
|
||||
{bool nonInstanceAccessIsError: false}) {
|
||||
helper.addProblem(templateNotAType.withArguments(token.lexeme),
|
||||
offsetForToken(token), lengthForToken(token));
|
||||
return const InvalidType();
|
||||
}
|
||||
|
||||
/* kernel.Expression | Generator */ buildThrowNoSuchMethodError(
|
||||
kernel.Expression receiver, Arguments arguments,
|
||||
{bool isSuper: false,
|
||||
bool isGetter: false,
|
||||
bool isSetter: false,
|
||||
bool isStatic: false,
|
||||
String name,
|
||||
int offset,
|
||||
LocatedMessage argMessage}) {
|
||||
return helper.throwNoSuchMethodError(receiver, name ?? plainNameForWrite,
|
||||
arguments, offset ?? offsetForToken(this.token),
|
||||
isGetter: isGetter,
|
||||
isSetter: isSetter,
|
||||
isSuper: isSuper,
|
||||
isStatic: isStatic,
|
||||
argMessage: argMessage);
|
||||
}
|
||||
|
||||
bool get isThisPropertyAccess => false;
|
||||
|
||||
void printOn(StringSink sink);
|
||||
|
||||
String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.write(debugName);
|
||||
buffer.write("(offset: ");
|
||||
buffer.write("${offsetForToken(token)}");
|
||||
printOn(buffer);
|
||||
buffer.write(")");
|
||||
return "$buffer";
|
||||
}
|
||||
}
|
||||
|
||||
class VariableUseGenerator<Arguments> extends Generator<Arguments> {
|
||||
final VariableDeclaration variable;
|
||||
|
@ -361,7 +440,7 @@ class PropertyAccessGenerator<Arguments> extends Generator<Arguments> {
|
|||
this.setter)
|
||||
: super(helper, token);
|
||||
|
||||
static FastaAccessor<Arguments> make<Arguments>(
|
||||
static Generator<Arguments> make<Arguments>(
|
||||
BuilderHelper<dynamic, dynamic, Arguments> helper,
|
||||
Token token,
|
||||
kernel.Expression receiver,
|
||||
|
@ -713,7 +792,7 @@ class IndexedAccessGenerator<Arguments> extends Generator<Arguments> {
|
|||
this.setter)
|
||||
: super(helper, token);
|
||||
|
||||
static FastaAccessor<Arguments> make<Arguments>(
|
||||
static Generator<Arguments> make<Arguments>(
|
||||
BuilderHelper<dynamic, dynamic, Arguments> helper,
|
||||
Token token,
|
||||
kernel.Expression receiver,
|
||||
|
@ -1256,10 +1335,10 @@ class LoadLibraryGenerator<Arguments> extends Generator<Arguments> {
|
|||
class DeferredAccessGenerator<Arguments> extends Generator<Arguments> {
|
||||
final PrefixBuilder builder;
|
||||
|
||||
final FastaAccessor accessor;
|
||||
final Generator generator;
|
||||
|
||||
DeferredAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
|
||||
Token token, this.builder, this.accessor)
|
||||
Token token, this.builder, this.generator)
|
||||
: super(helper, token);
|
||||
|
||||
String get plainNameForRead {
|
||||
|
@ -1271,18 +1350,18 @@ class DeferredAccessGenerator<Arguments> extends Generator<Arguments> {
|
|||
|
||||
kernel.Expression _makeSimpleRead() {
|
||||
return helper.wrapInDeferredCheck(
|
||||
accessor._makeSimpleRead(), builder, token.charOffset);
|
||||
generator._makeSimpleRead(), builder, token.charOffset);
|
||||
}
|
||||
|
||||
kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
|
||||
return helper.wrapInDeferredCheck(
|
||||
accessor._makeRead(complexAssignment), builder, token.charOffset);
|
||||
generator._makeRead(complexAssignment), builder, token.charOffset);
|
||||
}
|
||||
|
||||
kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
|
||||
ShadowComplexAssignment complexAssignment) {
|
||||
return helper.wrapInDeferredCheck(
|
||||
accessor._makeWrite(value, voidContext, complexAssignment),
|
||||
generator._makeWrite(value, voidContext, complexAssignment),
|
||||
builder,
|
||||
token.charOffset);
|
||||
}
|
||||
|
@ -1290,8 +1369,8 @@ class DeferredAccessGenerator<Arguments> extends Generator<Arguments> {
|
|||
buildPropertyAccess(
|
||||
IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
|
||||
var propertyAccess =
|
||||
accessor.buildPropertyAccess(send, operatorOffset, isNullAware);
|
||||
if (propertyAccess is FastaAccessor) {
|
||||
generator.buildPropertyAccess(send, operatorOffset, isNullAware);
|
||||
if (propertyAccess is Generator) {
|
||||
return new DeferredAccessGenerator(
|
||||
helper, token, builder, propertyAccess);
|
||||
} else {
|
||||
|
@ -1305,7 +1384,7 @@ class DeferredAccessGenerator<Arguments> extends Generator<Arguments> {
|
|||
{bool nonInstanceAccessIsError: false}) {
|
||||
helper.addProblem(
|
||||
templateDeferredTypeAnnotation.withArguments(
|
||||
accessor.buildTypeWithBuiltArguments(arguments,
|
||||
generator.buildTypeWithBuiltArguments(arguments,
|
||||
nonInstanceAccessIsError: nonInstanceAccessIsError),
|
||||
builder.name),
|
||||
offsetForToken(token),
|
||||
|
@ -1315,15 +1394,15 @@ class DeferredAccessGenerator<Arguments> extends Generator<Arguments> {
|
|||
|
||||
kernel.Expression doInvocation(int offset, Arguments arguments) {
|
||||
return helper.wrapInDeferredCheck(
|
||||
accessor.doInvocation(offset, arguments), builder, token.charOffset);
|
||||
generator.doInvocation(offset, arguments), builder, token.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
void printOn(StringSink sink) {
|
||||
sink.write(", builder: ");
|
||||
sink.write(builder);
|
||||
sink.write(", accessor: ");
|
||||
sink.write(accessor);
|
||||
sink.write(", generator: ");
|
||||
sink.write(generator);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -140,114 +140,6 @@ class FunctionTypeAccessor {
|
|||
this.positionalParameterCount, this._namedParameters);
|
||||
}
|
||||
|
||||
// TODO(ahe): Merge this into [Generator] when all uses have been updated.
|
||||
abstract class FastaAccessor<Arguments> implements Accessor<Arguments> {
|
||||
BuilderHelper<dynamic, dynamic, Arguments> get helper;
|
||||
|
||||
// TODO(ahe): Change type arguments.
|
||||
Forest<kernel.Expression, kernel.Statement, Token, Arguments> get forest =>
|
||||
helper.forest;
|
||||
|
||||
String get plainNameForRead;
|
||||
|
||||
String get debugName;
|
||||
|
||||
Uri get uri => helper.uri;
|
||||
|
||||
String get plainNameForWrite => plainNameForRead;
|
||||
|
||||
bool get isInitializer => false;
|
||||
|
||||
T storeOffset<T>(T node, int offset) {
|
||||
return helper.storeOffset(node, offset);
|
||||
}
|
||||
|
||||
kernel.Expression buildForEffect() => buildSimpleRead();
|
||||
|
||||
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
|
||||
int offset = offsetForToken(token);
|
||||
return helper.buildInvalidInitializer(
|
||||
helper.buildCompileTimeError(
|
||||
messageInvalidInitializer, offset, lengthForToken(token)),
|
||||
offset);
|
||||
}
|
||||
|
||||
kernel.Expression makeInvalidRead() {
|
||||
return buildThrowNoSuchMethodError(
|
||||
forest.literalNull(token), forest.argumentsEmpty(noLocation),
|
||||
isGetter: true);
|
||||
}
|
||||
|
||||
kernel.Expression makeInvalidWrite(kernel.Expression value) {
|
||||
return buildThrowNoSuchMethodError(forest.literalNull(token),
|
||||
forest.arguments(<kernel.Expression>[value], noLocation),
|
||||
isSetter: true);
|
||||
}
|
||||
|
||||
/* kernel.Expression | FastaAccessor | Initializer */ doInvocation(
|
||||
int offset, Arguments arguments);
|
||||
|
||||
/* kernel.Expression | FastaAccessor */ buildPropertyAccess(
|
||||
IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
|
||||
if (send is SendAccessor) {
|
||||
return helper.buildMethodInvocation(buildSimpleRead(), send.name,
|
||||
send.arguments, offsetForToken(send.token),
|
||||
isNullAware: isNullAware);
|
||||
} else {
|
||||
if (helper.constantContext != ConstantContext.none &&
|
||||
send.name != lengthName) {
|
||||
helper.deprecated_addCompileTimeError(
|
||||
offsetForToken(token), "Not a constant expression.");
|
||||
}
|
||||
return PropertyAccessGenerator.make(helper, send.token, buildSimpleRead(),
|
||||
send.name, null, null, isNullAware);
|
||||
}
|
||||
}
|
||||
|
||||
DartType buildTypeWithBuiltArguments(List<DartType> arguments,
|
||||
{bool nonInstanceAccessIsError: false}) {
|
||||
helper.addProblem(templateNotAType.withArguments(token.lexeme),
|
||||
offsetForToken(token), lengthForToken(token));
|
||||
return const InvalidType();
|
||||
}
|
||||
|
||||
/* kernel.Expression | FastaAccessor */ buildThrowNoSuchMethodError(
|
||||
kernel.Expression receiver, Arguments arguments,
|
||||
{bool isSuper: false,
|
||||
bool isGetter: false,
|
||||
bool isSetter: false,
|
||||
bool isStatic: false,
|
||||
String name,
|
||||
int offset,
|
||||
LocatedMessage argMessage}) {
|
||||
return helper.throwNoSuchMethodError(receiver, name ?? plainNameForWrite,
|
||||
arguments, offset ?? offsetForToken(this.token),
|
||||
isGetter: isGetter,
|
||||
isSetter: isSetter,
|
||||
isSuper: isSuper,
|
||||
isStatic: isStatic,
|
||||
argMessage: argMessage);
|
||||
}
|
||||
|
||||
bool get isThisPropertyAccess => false;
|
||||
|
||||
@override
|
||||
ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
|
||||
new ShadowIllegalAssignment(rhs);
|
||||
|
||||
void printOn(StringSink sink);
|
||||
|
||||
String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.write(debugName);
|
||||
buffer.write("(offset: ");
|
||||
buffer.write("${offsetForToken(token)}");
|
||||
printOn(buffer);
|
||||
buffer.write(")");
|
||||
return "$buffer";
|
||||
}
|
||||
}
|
||||
|
||||
class IncompleteError<Arguments> extends IncompleteSendGenerator<Arguments>
|
||||
with ErroneousExpressionGenerator<Arguments> {
|
||||
final Message message;
|
||||
|
@ -313,7 +205,7 @@ class SendAccessor<Arguments> extends IncompleteSendGenerator<Arguments> {
|
|||
}
|
||||
|
||||
withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
|
||||
if (receiver is FastaAccessor) {
|
||||
if (receiver is Generator) {
|
||||
return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
|
||||
}
|
||||
if (receiver is PrefixBuilder) {
|
||||
|
@ -398,7 +290,7 @@ class IncompletePropertyAccessor<Arguments>
|
|||
}
|
||||
|
||||
withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
|
||||
if (receiver is FastaAccessor) {
|
||||
if (receiver is Generator) {
|
||||
return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
|
||||
}
|
||||
if (receiver is PrefixBuilder) {
|
||||
|
@ -476,7 +368,7 @@ class TypeDeclarationAccessor<Arguments>
|
|||
/// the reference is not prefixed.
|
||||
final PrefixBuilder prefix;
|
||||
|
||||
/// The offset at which the [declaration] is referenced by this accessor,
|
||||
/// The offset at which the [declaration] is referenced by this generator,
|
||||
/// or `-1` if the reference is implicit.
|
||||
final int declarationReferenceOffset;
|
||||
|
||||
|
@ -535,11 +427,11 @@ class TypeDeclarationAccessor<Arguments>
|
|||
Builder builder = declaration.findStaticBuilder(
|
||||
name.name, offsetForToken(token), uri, helper.library);
|
||||
|
||||
FastaAccessor accessor;
|
||||
Generator generator;
|
||||
if (builder == null) {
|
||||
// If we find a setter, [builder] is an [AccessErrorBuilder], not null.
|
||||
if (send is IncompletePropertyAccessor) {
|
||||
accessor = new UnresolvedNameGenerator(helper, send.token, name);
|
||||
generator = new UnresolvedNameGenerator(helper, send.token, name);
|
||||
} else {
|
||||
return helper.buildConstructorInvocation(declaration, send.token,
|
||||
arguments, name.name, null, token.charOffset, Constness.implicit);
|
||||
|
@ -555,13 +447,13 @@ class TypeDeclarationAccessor<Arguments>
|
|||
} else if (builder.isField && !builder.isFinal) {
|
||||
setter = builder;
|
||||
}
|
||||
accessor = new StaticAccessGenerator.fromBuilder(
|
||||
generator = new StaticAccessGenerator.fromBuilder(
|
||||
helper, builder, send.token, setter);
|
||||
}
|
||||
|
||||
return arguments == null
|
||||
? accessor
|
||||
: accessor.doInvocation(offsetForToken(send.token), arguments);
|
||||
? generator
|
||||
: generator.doInvocation(offsetForToken(send.token), arguments);
|
||||
} else {
|
||||
return super.buildPropertyAccess(send, operatorOffset, isNullAware);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ import 'package:front_end/src/fasta/fasta_codes.dart'
|
|||
import 'package:front_end/src/fasta/kernel/expression_generator.dart'
|
||||
show
|
||||
DeferredAccessGenerator,
|
||||
FastaAccessor,
|
||||
Generator,
|
||||
IncompleteError,
|
||||
IncompletePropertyAccessor,
|
||||
IndexedAccessGenerator,
|
||||
|
@ -76,7 +76,7 @@ import 'package:front_end/src/fasta/kernel/kernel_body_builder.dart'
|
|||
|
||||
import 'package:front_end/src/fasta/scanner.dart' show Token, scanString;
|
||||
|
||||
void check(String expected, FastaAccessor<Arguments> generator) {
|
||||
void check(String expected, Generator<Arguments> generator) {
|
||||
Expect.stringEquals(expected, "$generator");
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ main() {
|
|||
KernelBodyBuilder helper = new KernelBodyBuilder(
|
||||
libraryBuilder, null, null, null, null, null, null, false, uri, null);
|
||||
|
||||
FastaAccessor accessor =
|
||||
Generator generator =
|
||||
new ThisAccessGenerator<Arguments>(helper, token, false);
|
||||
|
||||
Library library = new Library(uri);
|
||||
|
@ -137,12 +137,12 @@ main() {
|
|||
"DelayedAssignment(offset: 4, value: expression,"
|
||||
" assignmentOperator: +=)",
|
||||
new DelayedAssignment<Arguments>(
|
||||
helper, token, accessor, expression, assignmentOperator));
|
||||
helper, token, generator, expression, assignmentOperator));
|
||||
check(
|
||||
"DelayedPostfixIncrement(offset: 4, binaryOperator: +,"
|
||||
" interfaceTarget: $uri::#class1::myInterfaceTarget)",
|
||||
new DelayedPostfixIncrement<Arguments>(
|
||||
helper, token, accessor, binaryOperator, interfaceTarget));
|
||||
helper, token, generator, binaryOperator, interfaceTarget));
|
||||
check(
|
||||
"VariableUseGenerator(offset: 4, variable: dynamic #t1;\n,"
|
||||
" promotedType: void)",
|
||||
|
@ -206,10 +206,10 @@ main() {
|
|||
check(
|
||||
"DeferredAccessGenerator(offset: 4, "
|
||||
"builder: Instance of 'PrefixBuilder',"
|
||||
" accessor: ThisAccessGenerator(offset: 4, isInitializer: false,"
|
||||
" generator: ThisAccessGenerator(offset: 4, isInitializer: false,"
|
||||
" isSuper: false))",
|
||||
new DeferredAccessGenerator<Arguments>(
|
||||
helper, token, prefixBuilder, accessor));
|
||||
helper, token, prefixBuilder, generator));
|
||||
check(
|
||||
"ReadOnlyAccessGenerator(offset: 4, expression: expression,"
|
||||
" plainNameForRead: foo, value: null)",
|
||||
|
|
Loading…
Reference in a new issue