Start creating common superclass for generators

Change-Id: I9d8c95665eed15be45c2a5b734e541af73a7db91
Reviewed-on: https://dart-review.googlesource.com/56117
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Peter von der Ahé <ahe@google.com>
This commit is contained in:
Peter von der Ahé 2018-05-23 09:24:46 +00:00 committed by commit-bot@chromium.org
parent 2a7188523e
commit 2d79c356e0
10 changed files with 2504 additions and 2262 deletions

View file

@ -364,6 +364,28 @@ class AstBuildingForest
Statement yieldStatement(Token yieldKeyword, Token star,
Expression expression, Token semicolon) =>
astFactory.yieldStatement(yieldKeyword, star, expression, semicolon);
@override
Generator<Expression, Statement, _Arguments> variableUseGenerator(
ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
Token token,
VariableDeclarationStatement variable,
kernel.DartType promotedType) {
// TODO(brianwilkerson) Implement this.
throw new UnimplementedError();
}
@override
Generator<Expression, Statement, _Arguments> propertyAccessGenerator(
ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
Token token,
Expression receiver,
covariant name,
covariant getter,
covariant setter) {
// TODO(brianwilkerson) Implement this.
throw new UnimplementedError();
}
}
/// A data holder used to conform to the [Forest] API.

View file

@ -6,6 +6,9 @@ library fasta.body_builder;
import 'dart:core' hide MapEntry;
import 'package:kernel/ast.dart' as kernel
show Arguments, Expression, Statement;
import '../constant_context.dart' show ConstantContext;
import '../fasta_codes.dart' as fasta;
@ -118,8 +121,6 @@ import 'kernel_api.dart';
import 'kernel_ast_api.dart' hide Expression, Statement;
import 'kernel_ast_api.dart' as kernel show Expression, Statement;
import 'kernel_builder.dart';
import 'type_algorithms.dart' show calculateBounds;
@ -654,8 +655,11 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
}
@override
void finishFunction(List annotations, FormalParameters<Arguments> formals,
AsyncMarker asyncModifier, kernel.Statement body) {
void finishFunction(
List annotations,
FormalParameters<Expression, Statement, Arguments> formals,
AsyncMarker asyncModifier,
kernel.Statement body) {
debugEvent("finishFunction");
typePromoter.finished();
@ -753,7 +757,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
enterLocalScope(
null,
new FormalParameters<Arguments>(
new FormalParameters<Expression, Statement, Arguments>(
parameters.positionalParameters, null, -1)
.computeFormalParameterScope(scope, member, this));
@ -925,7 +929,8 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
if (arguments == null) {
push(new IncompletePropertyAccessGenerator(this, beginToken, name));
} else {
push(new SendAccessGenerator(this, beginToken, name, arguments));
push(new SendAccessGenerator(
this, beginToken, name, forest.castArguments(arguments)));
}
} else if (arguments == null) {
push(receiver);
@ -2094,7 +2099,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
@override
void endFunctionType(Token functionToken, Token endToken) {
debugEvent("FunctionType");
FormalParameters<Arguments> formals = pop();
FormalParameters<Expression, Statement, Arguments> formals = pop();
DartType returnType = pop();
List<TypeParameter> typeVariables = typeVariableBuildersToKernel(pop());
FunctionType type = formals.toFunctionType(returnType, typeVariables);
@ -2268,7 +2273,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
if (inCatchClause || functionNestingLevel != 0) {
exitLocalScope();
}
FormalParameters<Arguments> formals = pop();
FormalParameters<Expression, Statement, Arguments> formals = pop();
DartType returnType = pop();
List<TypeParameter> typeVariables = typeVariableBuildersToKernel(pop());
FunctionType type = formals.toFunctionType(returnType, typeVariables);
@ -2323,8 +2328,8 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
List<VariableDeclaration> variables =
new List<VariableDeclaration>.filled(count, null, growable: true);
popList(count, variables);
FormalParameters<Arguments> formals =
new FormalParameters(variables, optional, beginToken.charOffset);
var formals = new FormalParameters<Expression, Statement, Arguments>(
variables, optional, beginToken.charOffset);
constantContext = pop();
push(formals);
if ((inCatchClause || functionNestingLevel != 0) &&
@ -2358,7 +2363,8 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
if (catchKeyword != null) {
exitLocalScope();
}
FormalParameters<Arguments> catchParameters = popIfNotNull(catchKeyword);
FormalParameters<Expression, Statement, Arguments> catchParameters =
popIfNotNull(catchKeyword);
DartType type = popIfNotNull(onKeyword) ?? const DynamicType();
VariableDeclaration exception;
VariableDeclaration stackTrace;
@ -2421,7 +2427,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
lookupInstanceMember(indexGetName, isSuper: true),
lookupInstanceMember(indexSetName, isSuper: true)));
} else {
push(IndexedAccessGenerator.make<Arguments>(
push(IndexedAccessGenerator.make(
this,
openSquareBracket,
toKernelExpression(toValue(receiver)),
@ -2492,7 +2498,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
debugEvent("UnaryPostfixAssignmentExpression");
var generator = pop();
if (generator is Generator) {
push(new DelayedPostfixIncrement<Arguments>(
push(new DelayedPostfixIncrement(
this, token, generator, incrementOperator(token), null));
} else {
push(
@ -2794,7 +2800,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
? wrapInDeferredCheck(expression, deferredPrefix, checkOffset)
: expression);
} else if (type is ErroneousExpressionGenerator) {
push(type.buildError(arguments));
push(type.buildError(forest.castArguments(arguments)));
} else {
push(throwNoSuchMethodError(storeOffset(forest.literalNull(null), offset),
debugName(getNodeName(type), name), arguments, nameToken.charOffset));
@ -3018,7 +3024,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
Statement body = popStatement();
AsyncMarker asyncModifier = pop();
exitLocalScope();
FormalParameters<Arguments> formals = pop();
FormalParameters<Expression, Statement, Arguments> formals = pop();
var declaration = pop();
var returnType = pop();
var hasImplicitReturnType = returnType == null;
@ -3115,7 +3121,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
Statement body = popStatement();
AsyncMarker asyncModifier = pop();
exitLocalScope();
FormalParameters<Arguments> formals = pop();
FormalParameters<Expression, Statement, Arguments> formals = pop();
exitFunction();
List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
FunctionNode function = formals.addToFunction(new FunctionNode(
@ -4209,11 +4215,12 @@ class Label {
String toString() => "label($name)";
}
abstract class ContextAwareGenerator<Arguments> extends Generator<Arguments> {
abstract class ContextAwareGenerator
extends Generator<kernel.Expression, kernel.Statement, kernel.Arguments> {
final Generator generator;
ContextAwareGenerator(
ExpressionGeneratorHelper<dynamic, dynamic, Arguments> helper,
ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
Token token,
this.generator)
: super(helper, token);
@ -4222,7 +4229,7 @@ abstract class ContextAwareGenerator<Arguments> extends Generator<Arguments> {
return unsupported("plainNameForRead", token.charOffset, helper.uri);
}
kernel.Expression doInvocation(int charOffset, Arguments arguments) {
kernel.Expression doInvocation(int charOffset, kernel.Arguments arguments) {
return unhandled("${runtimeType}", "doInvocation", charOffset, uri);
}
@ -4275,17 +4282,13 @@ abstract class ContextAwareGenerator<Arguments> extends Generator<Arguments> {
}
}
class DelayedAssignment<Arguments> extends ContextAwareGenerator<Arguments> {
class DelayedAssignment extends ContextAwareGenerator {
final kernel.Expression value;
final String assignmentOperator;
DelayedAssignment(
ExpressionGeneratorHelper<dynamic, dynamic, Arguments> helper,
Token token,
Generator generator,
this.value,
this.assignmentOperator)
DelayedAssignment(ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
Token token, Generator generator, this.value, this.assignmentOperator)
: super(helper, token, generator);
String get debugName => "DelayedAssignment";
@ -4367,14 +4370,13 @@ class DelayedAssignment<Arguments> extends ContextAwareGenerator<Arguments> {
}
}
class DelayedPostfixIncrement<Arguments>
extends ContextAwareGenerator<Arguments> {
class DelayedPostfixIncrement extends ContextAwareGenerator {
final Name binaryOperator;
final Procedure interfaceTarget;
DelayedPostfixIncrement(
ExpressionGeneratorHelper<dynamic, dynamic, Arguments> helper,
ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
Token token,
Generator generator,
this.binaryOperator,
@ -4536,7 +4538,7 @@ class OptionalFormals {
OptionalFormals(this.kind, this.formals);
}
class FormalParameters<Arguments> {
class FormalParameters<Expression, Statement, Arguments> {
final List<VariableDeclaration> required;
final OptionalFormals optional;
final int charOffset;

File diff suppressed because it is too large Load diff

View file

@ -10,8 +10,8 @@ import 'package:kernel/ast.dart'
show
Arguments,
AssertInitializer,
BreakStatement,
Block,
BreakStatement,
Catch,
ContinueSwitchStatement,
DartType,
@ -23,6 +23,8 @@ import 'package:kernel/ast.dart'
Let,
LibraryDependency,
MapEntry,
Member,
Name,
NamedExpression,
Statement,
SwitchCase,
@ -37,6 +39,9 @@ import '../problems.dart' show unsupported;
import '../scanner.dart' show Token;
import 'kernel_expression_generator.dart'
show KernelPropertyAccessGenerator, KernelVariableUseGenerator;
import 'kernel_shadow_ast.dart'
show
ShadowArguments,
@ -76,7 +81,7 @@ import 'kernel_shadow_ast.dart'
ShadowWhileStatement,
ShadowYieldStatement;
import 'forest.dart' show Forest;
import 'forest.dart' show ExpressionGeneratorHelper, Forest;
/// A shadow tree factory.
class Fangorn extends Forest<Expression, Statement, Token, Arguments> {
@ -498,6 +503,28 @@ class Fangorn extends Forest<Expression, Statement, Token, Arguments> {
SwitchCase target, ContinueSwitchStatement user) {
user.target = target;
}
@override
KernelVariableUseGenerator variableUseGenerator(
ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
Token token,
VariableDeclaration variable,
DartType promotedType) {
return new KernelVariableUseGenerator(
helper, token, variable, promotedType);
}
@override
KernelPropertyAccessGenerator propertyAccessGenerator(
ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
Token token,
Expression receiver,
Name name,
Member getter,
Member setter) {
return new KernelPropertyAccessGenerator.internal(
helper, token, receiver, name, getter, setter);
}
}
class _VariablesDeclaration extends Statement {

View file

@ -9,8 +9,16 @@ import 'package:kernel/ast.dart' as kernel show Arguments, DartType;
import 'body_builder.dart' show Identifier;
import 'expression_generator.dart' show Generator;
import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
export 'body_builder.dart' show Identifier, Operator;
export 'expression_generator.dart' show Generator;
export 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
/// A tree factory.
///
/// For now, the [Location] is always a token.
@ -278,6 +286,20 @@ abstract class Forest<Expression, Statement, Location, Arguments> {
void resolveContinueInSwitch(
covariant Object target, covariant Statement user);
Generator<Expression, Statement, Arguments> variableUseGenerator(
ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
Location location,
covariant variable,
kernel.DartType promotedType);
Generator<Expression, Statement, Arguments> propertyAccessGenerator(
ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
Location location,
Expression receiver,
covariant name,
covariant getter,
covariant setter);
// TODO(ahe): Remove this method when all users are moved here.
kernel.Arguments castArguments(Arguments arguments) {
dynamic a = arguments;

View file

@ -0,0 +1,445 @@
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// 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:kernel/ast.dart' show Arguments, Expression, Node, Statement;
import '../../scanner/token.dart' show Token;
import '../constant_context.dart' show ConstantContext;
import '../fasta_codes.dart'
show
LocatedMessage,
messageLoadLibraryTakesNoArguments,
messageSuperAsExpression,
templateDeferredTypeAnnotation,
templateIntegerLiteralIsOutOfRange,
templateNotAPrefixInTypeAnnotation,
templateUnresolvedPrefixInTypeAnnotation;
import '../messages.dart' show Message, noLength;
import '../names.dart' show callName, equalsName, indexGetName, indexSetName;
import '../parser.dart' show lengthForToken, lengthOfSpan, offsetForToken;
import '../problems.dart' show unhandled, unsupported;
import '../scope.dart' show AccessErrorBuilder;
import 'body_builder.dart' show Identifier, noLocation;
import 'constness.dart' show Constness;
import 'expression_generator.dart'
show
ExpressionGenerator,
Generator,
PropertyAccessGenerator,
VariableUseGenerator;
import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
import 'forest.dart' show Forest;
import 'kernel_builder.dart' show LoadLibraryBuilder, PrefixBuilder;
import 'kernel_api.dart' show NameSystem, printNodeOn, printQualifiedNameOn;
import 'kernel_ast_api.dart'
show
Constructor,
DartType,
Field,
Initializer,
InvalidType,
Let,
Member,
Name,
Procedure,
PropertySet,
ShadowComplexAssignment,
ShadowIllegalAssignment,
ShadowIndexAssign,
ShadowMethodInvocation,
ShadowNullAwarePropertyGet,
ShadowPropertyAssign,
ShadowPropertyGet,
ShadowStaticAssignment,
ShadowSuperMethodInvocation,
ShadowSuperPropertyGet,
ShadowVariableAssignment,
ShadowVariableDeclaration,
ShadowVariableGet,
StaticSet,
SuperMethodInvocation,
SuperPropertySet,
Throw,
TreeNode,
TypeParameter,
TypeParameterType,
VariableDeclaration,
VariableGet,
VariableSet;
import 'kernel_builder.dart'
show
Builder,
BuiltinTypeBuilder,
FunctionTypeAliasBuilder,
KernelClassBuilder,
KernelFunctionTypeAliasBuilder,
KernelInvalidTypeBuilder,
KernelTypeVariableBuilder,
LoadLibraryBuilder,
PrefixBuilder,
TypeDeclarationBuilder;
part 'kernel_expression_generator_impl.dart';
abstract class KernelExpressionGenerator
implements ExpressionGenerator<Expression, Statement, Arguments> {
ExpressionGeneratorHelper<Expression, Statement, Arguments> get helper;
Token get token;
Forest<Expression, Statement, Token, Arguments> get forest;
@override
Expression buildSimpleRead() {
return _finish(_makeSimpleRead(), null);
}
@override
Expression buildAssignment(Expression value, {bool voidContext: false}) {
var complexAssignment = startComplexAssignment(value);
return _finish(_makeSimpleWrite(value, voidContext, complexAssignment),
complexAssignment);
}
@override
Expression buildNullAwareAssignment(
Expression value, DartType type, int offset,
{bool voidContext: false}) {
var complexAssignment = startComplexAssignment(value);
if (voidContext) {
var nullAwareCombiner = helper.storeOffset(
forest.conditionalExpression(
buildIsNull(_makeRead(complexAssignment), offset, helper),
null,
_makeWrite(value, false, complexAssignment),
null,
helper.storeOffset(forest.literalNull(null), offset)),
offset);
complexAssignment?.nullAwareCombiner = nullAwareCombiner;
return _finish(nullAwareCombiner, complexAssignment);
}
var tmp = new VariableDeclaration.forValue(_makeRead(complexAssignment));
var nullAwareCombiner = helper.storeOffset(
forest.conditionalExpression(
buildIsNull(new VariableGet(tmp), offset, helper),
null,
_makeWrite(value, false, complexAssignment),
null,
new VariableGet(tmp)),
offset);
complexAssignment?.nullAwareCombiner = nullAwareCombiner;
return _finish(makeLet(tmp, nullAwareCombiner), complexAssignment);
}
@override
Expression buildCompoundAssignment(Name binaryOperator, Expression value,
{int offset: TreeNode.noOffset,
bool voidContext: false,
Procedure interfaceTarget,
bool isPreIncDec: false}) {
var complexAssignment = startComplexAssignment(value);
complexAssignment?.isPreIncDec = isPreIncDec;
var combiner = makeBinary(_makeRead(complexAssignment), binaryOperator,
interfaceTarget, value, helper,
offset: offset);
complexAssignment?.combiner = combiner;
return _finish(_makeWrite(combiner, voidContext, complexAssignment),
complexAssignment);
}
@override
Expression buildPrefixIncrement(Name binaryOperator,
{int offset: TreeNode.noOffset,
bool voidContext: false,
Procedure interfaceTarget}) {
return buildCompoundAssignment(
binaryOperator, helper.storeOffset(forest.literalInt(1, null), offset),
offset: offset,
voidContext: voidContext,
interfaceTarget: interfaceTarget,
isPreIncDec: true);
}
@override
Expression buildPostfixIncrement(Name binaryOperator,
{int offset: TreeNode.noOffset,
bool voidContext: false,
Procedure interfaceTarget}) {
if (voidContext) {
return buildPrefixIncrement(binaryOperator,
offset: offset, voidContext: true, interfaceTarget: interfaceTarget);
}
var rhs = helper.storeOffset(forest.literalInt(1, null), offset);
var complexAssignment = startComplexAssignment(rhs);
var value = new VariableDeclaration.forValue(_makeRead(complexAssignment));
valueAccess() => new VariableGet(value);
var combiner = makeBinary(
valueAccess(), binaryOperator, interfaceTarget, rhs, helper,
offset: offset);
complexAssignment?.combiner = combiner;
complexAssignment?.isPostIncDec = true;
var dummy = new ShadowVariableDeclaration.forValue(
_makeWrite(combiner, true, complexAssignment),
helper.functionNestingLevel);
return _finish(
makeLet(value, makeLet(dummy, valueAccess())), complexAssignment);
}
@override
Expression makeInvalidRead() {
return buildThrowNoSuchMethodError(
forest.literalNull(token), forest.argumentsEmpty(noLocation),
isGetter: true);
}
@override
Expression makeInvalidWrite(Expression value) {
return buildThrowNoSuchMethodError(forest.literalNull(token),
forest.arguments(<Expression>[value], noLocation),
isSetter: true);
}
Expression _makeSimpleRead() => _makeRead(null);
Expression _makeSimpleWrite(Expression value, bool voidContext,
ShadowComplexAssignment complexAssignment) {
return _makeWrite(value, voidContext, complexAssignment);
}
Expression _makeRead(ShadowComplexAssignment complexAssignment);
Expression _makeWrite(Expression value, bool voidContext,
ShadowComplexAssignment complexAssignment);
Expression _finish(
Expression body, ShadowComplexAssignment complexAssignment) {
if (complexAssignment != null) {
complexAssignment.desugared = body;
return complexAssignment;
} else {
return body;
}
}
/// Creates a data structure for tracking the desugaring of a complex
/// assignment expression whose right hand side is [rhs].
ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
new ShadowIllegalAssignment(rhs);
}
abstract class KernelGenerator = Generator<Expression, Statement, Arguments>
with KernelExpressionGenerator;
class KernelVariableUseGenerator extends KernelGenerator
with VariableUseGenerator<Expression, Statement, Arguments> {
final VariableDeclaration variable;
final DartType promotedType;
KernelVariableUseGenerator(
ExpressionGeneratorHelper<dynamic, dynamic, Arguments> helper,
Token token,
this.variable,
this.promotedType)
: super(helper, token);
@override
String get plainNameForRead => variable.name;
@override
Expression _makeRead(ShadowComplexAssignment complexAssignment) {
var fact = helper.typePromoter
.getFactForAccess(variable, helper.functionNestingLevel);
var scope = helper.typePromoter.currentScope;
var read = new ShadowVariableGet(variable, fact, scope)
..fileOffset = offsetForToken(token);
complexAssignment?.read = read;
return read;
}
@override
Expression _makeWrite(Expression value, bool voidContext,
ShadowComplexAssignment complexAssignment) {
helper.typePromoter.mutateVariable(variable, helper.functionNestingLevel);
var write = variable.isFinal || variable.isConst
? makeInvalidWrite(value)
: new VariableSet(variable, value)
..fileOffset = offsetForToken(token);
complexAssignment?.write = write;
return write;
}
@override
Expression doInvocation(int offset, Arguments arguments) {
return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
adjustForImplicitCall(plainNameForRead, offset),
isImplicitCall: true);
}
@override
ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
new ShadowVariableAssignment(rhs);
@override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
sink.write(", variable: ");
printNodeOn(variable, sink, syntheticNames: syntheticNames);
sink.write(", promotedType: ");
printNodeOn(promotedType, sink, syntheticNames: syntheticNames);
}
}
class KernelPropertyAccessGenerator extends KernelGenerator
with PropertyAccessGenerator<Expression, Statement, Arguments> {
final Expression receiver;
final Name name;
final Member getter;
final Member setter;
VariableDeclaration _receiverVariable;
KernelPropertyAccessGenerator.internal(
ExpressionGeneratorHelper<dynamic, dynamic, Arguments> helper,
Token token,
this.receiver,
this.name,
this.getter,
this.setter)
: super(helper, token);
@override
String get plainNameForRead => name.name;
receiverAccess() {
_receiverVariable ??= new VariableDeclaration.forValue(receiver);
return new VariableGet(_receiverVariable)
..fileOffset = offsetForToken(token);
}
@override
Expression doInvocation(int offset, Arguments arguments) {
return helper.buildMethodInvocation(receiver, name, arguments, offset);
}
@override
ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
new ShadowPropertyAssign(receiver, rhs);
@override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
sink.write(", _receiverVariable: ");
printNodeOn(_receiverVariable, sink, syntheticNames: syntheticNames);
sink.write(", receiver: ");
printNodeOn(receiver, sink, syntheticNames: syntheticNames);
sink.write(", name: ");
sink.write(name.name);
sink.write(", getter: ");
printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
sink.write(", setter: ");
printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
}
@override
Expression _makeSimpleRead() => new ShadowPropertyGet(receiver, name, getter)
..fileOffset = offsetForToken(token);
@override
Expression _makeSimpleWrite(Expression value, bool voidContext,
ShadowComplexAssignment complexAssignment) {
var write = new PropertySet(receiver, name, value, setter)
..fileOffset = offsetForToken(token);
complexAssignment?.write = write;
return write;
}
@override
Expression _makeRead(ShadowComplexAssignment complexAssignment) {
var read = new ShadowPropertyGet(receiverAccess(), name, getter)
..fileOffset = offsetForToken(token);
complexAssignment?.read = read;
return read;
}
@override
Expression _makeWrite(Expression value, bool voidContext,
ShadowComplexAssignment complexAssignment) {
var write = new PropertySet(receiverAccess(), name, value, setter)
..fileOffset = offsetForToken(token);
complexAssignment?.write = write;
return write;
}
@override
Expression _finish(
Expression body, ShadowComplexAssignment complexAssignment) {
return super._finish(makeLet(_receiverVariable, body), complexAssignment);
}
}
Expression makeLet(VariableDeclaration variable, Expression body) {
if (variable == null) return body;
return new Let(variable, body);
}
Expression makeBinary(
Expression left,
Name operator,
Procedure interfaceTarget,
Expression right,
ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
{int offset: TreeNode.noOffset}) {
return new ShadowMethodInvocation(
left,
operator,
helper.storeOffset(
helper.forest.castArguments(
helper.forest.arguments(<Expression>[right], null)),
offset),
interfaceTarget: interfaceTarget)
..fileOffset = offset;
}
Expression buildIsNull(Expression value, int offset,
ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper) {
return makeBinary(value, equalsName, null,
helper.storeOffset(helper.forest.literalNull(null), offset), helper,
offset: offset);
}
VariableDeclaration makeOrReuseVariable(Expression value) {
// TODO: Devise a way to remember if a variable declaration was reused
// or is fresh (hence needs a let binding).
return new VariableDeclaration.forValue(value);
}
int adjustForImplicitCall(String name, int offset) {
// 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 offset + (name?.length ?? 0);
}
bool isFieldOrGetter(Member member) {
return member is Field || (member is Procedure && member.isGetter);
}

File diff suppressed because it is too large Load diff

View file

@ -67,10 +67,10 @@ import '../type_inference/type_schema_environment.dart'
import 'body_builder.dart' show combineStatements;
import 'expression_generator.dart' show makeLet;
import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
import 'kernel_expression_generator.dart' show makeLet;
/// Indicates whether type inference involving conditional expressions should
/// always use least upper bound.
///

View file

@ -62,11 +62,11 @@ import '../../base/instrumentation.dart'
import '../fasta_codes.dart';
import '../kernel/expression_generator.dart' show buildIsNull;
import '../kernel/expression_generator_helper.dart'
show ExpressionGeneratorHelper;
import '../kernel/kernel_expression_generator.dart' show buildIsNull;
import '../kernel/kernel_shadow_ast.dart'
show
getExplicitTypeArguments,

View file

@ -18,6 +18,7 @@ import 'package:kernel/ast.dart'
Name,
Procedure,
ProcedureKind,
Statement,
StringLiteral,
TypeParameter,
VariableDeclaration,
@ -44,18 +45,27 @@ import 'package:front_end/src/fasta/kernel/kernel_target.dart'
import 'package:front_end/src/fasta/fasta_codes.dart'
show Message, templateUnspecified;
import 'package:front_end/src/fasta/kernel/body_builder.dart'
show DelayedAssignment, DelayedPostfixIncrement;
import 'package:front_end/src/fasta/kernel/expression_generator.dart'
show Generator;
import 'package:front_end/src/fasta/kernel/kernel_body_builder.dart'
show KernelBodyBuilder;
import 'package:front_end/src/fasta/kernel/kernel_expression_generator.dart'
show
DeferredAccessGenerator,
Generator,
IncompleteErrorGenerator,
IncompletePropertyAccessGenerator,
IndexedAccessGenerator,
KernelPropertyAccessGenerator,
KernelVariableUseGenerator,
LargeIntAccessGenerator,
LoadLibraryGenerator,
NullAwarePropertyAccessGenerator,
ParenthesizedExpressionGenerator,
PropertyAccessGenerator,
ReadOnlyAccessGenerator,
SendAccessGenerator,
StaticAccessGenerator,
@ -65,18 +75,12 @@ import 'package:front_end/src/fasta/kernel/expression_generator.dart'
ThisIndexedAccessGenerator,
ThisPropertyAccessGenerator,
TypeDeclarationAccessGenerator,
UnresolvedNameGenerator,
VariableUseGenerator;
import 'package:front_end/src/fasta/kernel/body_builder.dart'
show DelayedAssignment, DelayedPostfixIncrement;
import 'package:front_end/src/fasta/kernel/kernel_body_builder.dart'
show KernelBodyBuilder;
UnresolvedNameGenerator;
import 'package:front_end/src/fasta/scanner.dart' show Token, scanString;
void check(String expected, Generator<Arguments> generator) {
void check(
String expected, Generator<Expression, Statement, Arguments> generator) {
Expect.stringEquals(expected, "$generator");
}
@ -123,8 +127,7 @@ main() {
KernelBodyBuilder helper = new KernelBodyBuilder(
libraryBuilder, null, null, null, null, null, null, false, uri, null);
Generator generator =
new ThisAccessGenerator<Arguments>(helper, token, false);
Generator generator = new ThisAccessGenerator(helper, token, false);
Library library = new Library(uri);
Class cls = new Class();
@ -136,98 +139,91 @@ main() {
check(
"DelayedAssignment(offset: 4, value: expression,"
" assignmentOperator: +=)",
new DelayedAssignment<Arguments>(
new DelayedAssignment(
helper, token, generator, expression, assignmentOperator));
check(
"DelayedPostfixIncrement(offset: 4, binaryOperator: +,"
" interfaceTarget: $uri::#class1::myInterfaceTarget)",
new DelayedPostfixIncrement<Arguments>(
new DelayedPostfixIncrement(
helper, token, generator, binaryOperator, interfaceTarget));
check(
"VariableUseGenerator(offset: 4, variable: dynamic #t1;\n,"
" promotedType: void)",
new VariableUseGenerator<Arguments>(helper, token, variable, type));
new KernelVariableUseGenerator(helper, token, variable, type));
check(
"PropertyAccessGenerator(offset: 4, _receiverVariable: null,"
" receiver: expression, name: bar, getter: $uri::myGetter,"
" setter: $uri::mySetter)",
new PropertyAccessGenerator<Arguments>.internal(
new KernelPropertyAccessGenerator.internal(
helper, token, expression, name, getter, setter));
check(
"ThisPropertyAccessGenerator(offset: 4, name: bar,"
" getter: $uri::myGetter, setter: $uri::mySetter)",
new ThisPropertyAccessGenerator<Arguments>(
helper, token, name, getter, setter));
new ThisPropertyAccessGenerator(helper, token, name, getter, setter));
check(
"NullAwarePropertyAccessGenerator(offset: 4,"
" receiver: final dynamic #t1 = expression;\n,"
" receiverExpression: expression, name: bar, getter: $uri::myGetter,"
" setter: $uri::mySetter, type: void)",
new NullAwarePropertyAccessGenerator<Arguments>(
new NullAwarePropertyAccessGenerator(
helper, token, expression, name, getter, setter, type));
check(
"SuperPropertyAccessGenerator(offset: 4, name: bar,"
" getter: $uri::myGetter, setter: $uri::mySetter)",
new SuperPropertyAccessGenerator<Arguments>(
helper, token, name, getter, setter));
new SuperPropertyAccessGenerator(helper, token, name, getter, setter));
check(
"IndexedAccessGenerator(offset: 4, receiver: expression, index: index,"
" getter: $uri::myGetter, setter: $uri::mySetter,"
" receiverVariable: null, indexVariable: null)",
new IndexedAccessGenerator<Arguments>.internal(
new IndexedAccessGenerator.internal(
helper, token, expression, index, getter, setter));
check(
"ThisIndexedAccessGenerator(offset: 4, index: index,"
" getter: $uri::myGetter, setter: $uri::mySetter, indexVariable: null)",
new ThisIndexedAccessGenerator<Arguments>(
helper, token, index, getter, setter));
new ThisIndexedAccessGenerator(helper, token, index, getter, setter));
check(
"SuperIndexedAccessGenerator(offset: 4, index: index,"
" getter: $uri::myGetter, setter: $uri::mySetter, indexVariable: null)",
new SuperIndexedAccessGenerator<Arguments>(
helper, token, index, getter, setter));
new SuperIndexedAccessGenerator(helper, token, index, getter, setter));
check(
"StaticAccessGenerator(offset: 4, readTarget: $uri::myGetter,"
" writeTarget: $uri::mySetter)",
new StaticAccessGenerator<Arguments>(helper, token, getter, setter));
new StaticAccessGenerator(helper, token, getter, setter));
check(
"LoadLibraryGenerator(offset: 4,"
" builder: Instance of 'LoadLibraryBuilder')",
new LoadLibraryGenerator<Arguments>(helper, token, loadLibraryBuilder));
new LoadLibraryGenerator(helper, token, loadLibraryBuilder));
check(
"ThisAccessGenerator(offset: 4, isInitializer: false, isSuper: false)",
new ThisAccessGenerator<Arguments>(helper, token, false));
new ThisAccessGenerator(helper, token, false));
check("IncompleteErrorGenerator(offset: 4, message: Unspecified)",
new IncompleteErrorGenerator<Arguments>(helper, token, message));
new IncompleteErrorGenerator(helper, token, message));
check("SendAccessGenerator(offset: 4, name: bar, arguments: (\"arg\"))",
new SendAccessGenerator<Arguments>(helper, token, name, arguments));
new SendAccessGenerator(helper, token, name, arguments));
check("IncompletePropertyAccessGenerator(offset: 4, name: bar)",
new IncompletePropertyAccessGenerator<Arguments>(helper, token, name));
new IncompletePropertyAccessGenerator(helper, token, name));
check(
"DeferredAccessGenerator(offset: 4, "
"builder: Instance of 'PrefixBuilder',"
" generator: ThisAccessGenerator(offset: 4, isInitializer: false,"
" isSuper: false))",
new DeferredAccessGenerator<Arguments>(
helper, token, prefixBuilder, generator));
new DeferredAccessGenerator(helper, token, prefixBuilder, generator));
check(
"ReadOnlyAccessGenerator(offset: 4, expression: expression,"
" plainNameForRead: foo, value: null)",
new ReadOnlyAccessGenerator<Arguments>(
helper, token, expression, "foo"));
new ReadOnlyAccessGenerator(helper, token, expression, "foo"));
check("LargeIntAccessGenerator(offset: 4, lexeme: myToken)",
new LargeIntAccessGenerator<Arguments>(helper, token));
new LargeIntAccessGenerator(helper, token));
check(
"ParenthesizedExpressionGenerator(offset: 4, expression: expression,"
" plainNameForRead: null, value: null)",
new ParenthesizedExpressionGenerator<Arguments>(
helper, token, expression));
new ParenthesizedExpressionGenerator(helper, token, expression));
check(
"TypeDeclarationAccessGenerator(offset: 4, expression: T,"
" plainNameForRead: foo, value: null)",
new TypeDeclarationAccessGenerator<Arguments>(
new TypeDeclarationAccessGenerator(
helper, token, prefixBuilder, -1, declaration, "foo"));
check("UnresolvedNameGenerator(offset: 4, name: bar)",
new UnresolvedNameGenerator<Arguments>(helper, token, name));
new UnresolvedNameGenerator(helper, token, name));
});
}