Index: pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
index 99d52df96e4e934f17d9a0273722e96a9d053a75..fbdeef31713749ce212dc0ac77d6d562adc1db29 100644 |
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
@@ -10,6 +10,11 @@ import '../parser/error_kind.dart' show ErrorKind; |
import '../parser/identifier_context.dart' show IdentifierContext; |
+import 'package:front_end/src/fasta/builder/ast_factory.dart'; |
+import 'package:front_end/src/fasta/kernel/kernel_ast_factory.dart'; |
+import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; |
+import 'package:front_end/src/fasta/type_inference/local_type_inferrer.dart'; |
+import '../builder/shadow_ast.dart'; |
import 'package:kernel/ast.dart'; |
import 'package:kernel/clone.dart' show CloneVisitor; |
@@ -102,19 +107,26 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
// from VM engineers. TODO(ahe): Does this still apply? |
int currentLocalVariableModifiers = -1; |
+ final AstFactory _ast = new KernelAstFactory(); |
+ |
+ final LocalTypeInferrer _typeInferrer; |
+ |
BodyBuilder( |
KernelLibraryBuilder library, |
this.member, |
Scope scope, |
this.formalParameterScope, |
this.hierarchy, |
- this.coreTypes, |
+ CoreTypes coreTypes, |
this.classBuilder, |
this.isInstanceMember, |
this.uri) |
- : enclosingScope = scope, |
+ : coreTypes = coreTypes, |
+ enclosingScope = scope, |
library = library, |
isDartLibrary = library.uri.scheme == "dart", |
+ // TODO(paulberry): put this behind a flag. |
+ _typeInferrer = new LocalTypeInferrer(coreTypes), |
super(scope); |
bool get hasParserError => recoverableErrors.isNotEmpty; |
@@ -133,23 +145,23 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
super.push(node); |
} |
- Expression popForValue() => toValue(pop()); |
+ ShadowExpression popForValue() => toValue(pop()); |
- Expression popForEffect() => toEffect(pop()); |
+ ShadowExpression popForEffect() => toEffect(pop()); |
- Expression popForValueIfNotNull(Object value) { |
+ ShadowExpression popForValueIfNotNull(Object value) { |
return value == null ? null : popForValue(); |
} |
@override |
- Expression toValue(Object node) { |
+ ShadowExpression toValue(Object node) { |
if (node is UnresolvedIdentifier) { |
if (isDartLibrary && |
node.name.name == "main" && |
library.uri.path == "_builtin" && |
member?.name == "_getMainClosure") { |
// TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 |
- return new NullLiteral()..fileOffset = node.fileOffset; |
+ return _ast.nullLiteral(node.fileOffset); |
} |
return throwNoSuchMethodError( |
node.name.name, new Arguments.empty(), node.fileOffset, |
@@ -166,13 +178,14 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
addCompileTimeError(-1, |
"Type variable can't be used as a constant expression $type."); |
} |
- return new TypeLiteral(type); |
+ return new TypeLiteral(type) as ShadowExpression; |
} |
} else if (node is TypeDeclarationBuilder) { |
- return new TypeLiteral(node.buildTypesWithBuiltArguments(library, null)); |
+ return new TypeLiteral(node.buildTypesWithBuiltArguments(library, null)) |
+ as ShadowExpression; |
} else if (node is KernelTypeBuilder) { |
- return new TypeLiteral(node.build(library)); |
- } else if (node is Expression) { |
+ return new TypeLiteral(node.build(library)) as ShadowExpression; |
+ } else if (node is ShadowExpression) { |
return node; |
} else if (node is PrefixBuilder) { |
return buildCompileTimeError("A library can't be used as an expression."); |
@@ -183,30 +196,28 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
} |
} |
- Expression toEffect(Object node) { |
+ ShadowExpression toEffect(Object node) { |
if (node is BuilderAccessor) return node.buildForEffect(); |
return toValue(node); |
} |
- List<Expression> popListForValue(int n) { |
- List<Expression> list = |
- new List<Expression>.filled(n, null, growable: true); |
+ List<ShadowExpression> popListForValue(int n) { |
+ List<ShadowExpression> list = _ast.expressionList(n); |
for (int i = n - 1; i >= 0; i--) { |
list[i] = popForValue(); |
} |
return list; |
} |
- List<Expression> popListForEffect(int n) { |
- List<Expression> list = |
- new List<Expression>.filled(n, null, growable: true); |
+ List<ShadowExpression> popListForEffect(int n) { |
+ List<ShadowExpression> list = _ast.expressionList(n); |
for (int i = n - 1; i >= 0; i--) { |
list[i] = popForEffect(); |
} |
return list; |
} |
- Block popBlock(int count, int charOffset) { |
+ ShadowBlock popBlock(int count, int charOffset) { |
List<dynamic /*Statement | List<Statement>*/ > statements = |
popList(count) ?? <Statement>[]; |
List<Statement> copy; |
@@ -221,7 +232,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
copy.add(statement); |
} |
} |
- return new Block(copy ?? statements)..fileOffset = charOffset; |
+ return _ast.block(copy ?? statements, charOffset); |
} |
Statement popStatementIfNotNull(Object value) { |
@@ -337,7 +348,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
assert(count == 0); |
push(NullValue.Block); |
} else { |
- Block block = popBlock(count, beginToken.charOffset); |
+ ShadowBlock block = popBlock(count, beginToken.charOffset); |
exitLocalScope(); |
push(block); |
} |
@@ -418,14 +429,14 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
} |
@override |
- void finishFunction( |
- FormalParameters formals, AsyncMarker asyncModifier, Statement body) { |
+ void finishFunction(FormalParameters formals, AsyncMarker asyncModifier, |
+ ShadowStatement body) { |
debugEvent("finishFunction"); |
KernelFunctionBuilder builder = member; |
if (builder is KernelConstructorBuilder) { |
if (asyncModifier != AsyncMarker.Sync) { |
// TODO(ahe): Change this to a null check. |
- addCompileTimeError(body?.fileOffset, |
+ addCompileTimeError((body as Statement)?.fileOffset, |
"Can't be marked as ${asyncModifier}: ${builder.name}"); |
} |
} else if (builder is KernelProcedureBuilder) { |
@@ -433,7 +444,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
} else { |
internalError("Unhandled: ${builder.runtimeType}"); |
} |
- builder.body = body; |
+ _typeInferrer.inferBody(body); |
+ builder.body = body as Statement; |
if (formals?.optional != null) { |
Iterator<FormalParameterBuilder> formalBuilders = |
builder.formals.skip(formals.required.length).iterator; |
@@ -450,7 +462,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void endExpressionStatement(Token token) { |
debugEvent("ExpressionStatement"); |
- push(new ExpressionStatement(popForEffect())); |
+ push(new ExpressionStatement(popForEffect() as Expression)); |
} |
@override |
@@ -469,7 +481,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
arguments[i] = new NamedExpression( |
"#$i", |
buildCompileTimeError( |
- "Expected named argument.", arguments[i].fileOffset)); |
+ "Expected named argument.", arguments[i].fileOffset) |
+ as Expression); |
} |
} |
} |
@@ -533,14 +546,14 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
receiver.name.name, arguments, receiver.fileOffset); |
} else { |
return buildMethodInvocation( |
- toValue(receiver), callName, arguments, charOffset); |
+ toValue(receiver) as Expression, callName, arguments, charOffset); |
} |
} |
@override |
void beginCascade(Token token) { |
debugEvent("beginCascade"); |
- Expression expression = popForValue(); |
+ Expression expression = popForValue() as Expression; |
if (expression is CascadeReceiver) { |
push(expression); |
push(new VariableAccessor( |
@@ -557,7 +570,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void endCascade() { |
debugEvent("endCascade"); |
- Expression expression = popForEffect(); |
+ Expression expression = popForEffect() as Expression; |
CascadeReceiver cascadeReceiver = pop(); |
cascadeReceiver.finalize(expression); |
push(cascadeReceiver); |
@@ -574,14 +587,15 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
} |
if (optional("??", token)) return doIfNull(token); |
if (optional("?.", token)) return doIfNotNull(token); |
- Expression argument = popForValue(); |
+ Expression argument = popForValue() as Expression; |
var receiver = pop(); |
bool isSuper = false; |
if (receiver is ThisAccessor && receiver.isSuper) { |
isSuper = true; |
receiver = new ThisExpression(); |
} |
- push(buildBinaryOperator(toValue(receiver), token, argument, isSuper)); |
+ push(buildBinaryOperator( |
+ toValue(receiver) as Expression, token, argument, isSuper)); |
} |
Expression buildBinaryOperator( |
@@ -594,7 +608,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
} |
if (!isBinaryOperator(operator) && !isMinusOperator(operator)) { |
return buildCompileTimeError( |
- "Not an operator: '$operator'.", token.charOffset); |
+ "Not an operator: '$operator'.", token.charOffset) as Expression; |
} else { |
Expression result = |
makeBinary(a, new Name(operator), null, b, token.charOffset); |
@@ -606,15 +620,15 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
} |
void doLogicalExpression(Token token) { |
- Expression argument = popForValue(); |
- Expression receiver = popForValue(); |
+ Expression argument = popForValue() as Expression; |
+ Expression receiver = popForValue() as Expression; |
push(new LogicalExpression(receiver, token.stringValue, argument)); |
} |
/// Handle `a ?? b`. |
void doIfNull(Token token) { |
- Expression b = popForValue(); |
- Expression a = popForValue(); |
+ Expression b = popForValue() as Expression; |
+ Expression a = popForValue() as Expression; |
VariableDeclaration variable = new VariableDeclaration.forValue(a); |
push(makeLet( |
variable, |
@@ -654,8 +668,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
} |
if (isNoSuchMethod) { |
return throwNoSuchMethodError( |
- node.name.name, node.arguments, node.fileOffset, |
- isSuper: true); |
+ node.name.name, node.arguments, node.fileOffset, isSuper: true) |
+ as Expression; |
} |
// TODO(ahe): Use [DirectPropertyGet] when possible. |
Expression receiver = new DirectPropertyGet(new ThisExpression(), target); |
@@ -670,7 +684,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
} |
@override |
- Expression throwNoSuchMethodError( |
+ ShadowExpression throwNoSuchMethodError( |
String name, Arguments arguments, int charOffset, |
{bool isSuper: false, isGetter: false, isSetter: false}) { |
String errorName = isSuper ? "super.$name" : name; |
@@ -693,7 +707,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
return new MapEntry(new SymbolLiteral(arg.name), arg.value); |
}).toList()), |
new NullLiteral() |
- ]))); |
+ ]))) as ShadowExpression; |
} |
@override |
@@ -860,7 +874,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
expressions.add(new StringLiteral(unescape(part.lexeme, quote))); |
} |
} else { |
- expressions.add(toValue(part)); |
+ expressions.add(toValue(part) as Expression); |
} |
} |
// Contains more than just \' or \". |
@@ -881,7 +895,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void handleStringJuxtaposition(int literalCount) { |
debugEvent("StringJuxtaposition"); |
- List<Expression> parts = popListForValue(literalCount); |
+ List<Expression> parts = popListForValue(literalCount) as List<Expression>; |
List<Expression> expressions; |
// Flatten string juxtapositions of string interpolation. |
for (int i = 0; i < parts.length; i++) { |
@@ -903,8 +917,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void handleLiteralInt(Token token) { |
debugEvent("LiteralInt"); |
- push( |
- new IntLiteral(int.parse(token.lexeme))..fileOffset = token.charOffset); |
+ push(_ast.intLiteral(int.parse(token.lexeme), token.charOffset)); |
} |
@override |
@@ -923,12 +936,12 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
void endReturnStatement( |
bool hasExpression, Token beginToken, Token endToken) { |
debugEvent("ReturnStatement"); |
- Expression expression = hasExpression ? popForValue() : null; |
+ ShadowExpression expression = hasExpression ? popForValue() : null; |
if (expression != null && inConstructor) { |
push(buildCompileTimeErrorStatement( |
"Can't return from a constructor.", beginToken.charOffset)); |
} else { |
- push(new ReturnStatement(expression)..fileOffset = beginToken.charOffset); |
+ push(_ast.returnStatement(expression, beginToken.charOffset)); |
} |
} |
@@ -936,7 +949,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
void endIfStatement(Token ifToken, Token elseToken) { |
Statement elsePart = popStatementIfNotNull(elseToken); |
Statement thenPart = popStatement(); |
- Expression condition = popForValue(); |
+ Expression condition = popForValue() as Expression; |
push(new IfStatement(condition, thenPart, elsePart)); |
} |
@@ -954,18 +967,22 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
pushNewLocalVariable(null); |
} |
- void pushNewLocalVariable(Expression initializer, |
+ void pushNewLocalVariable(ShadowExpression initializer, |
{int equalsCharOffset: TreeNode.noOffset}) { |
Identifier identifier = pop(); |
assert(currentLocalVariableModifiers != -1); |
bool isConst = (currentLocalVariableModifiers & constMask) != 0; |
bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; |
assert(isConst == constantExpressionRequired); |
- push(new VariableDeclaration(identifier.name, |
+ var variable = _ast.variableDeclaration(identifier.name, |
initializer: initializer, |
- type: currentLocalVariableType ?? const DynamicType(), |
+ type: currentLocalVariableType, |
isFinal: isFinal, |
- isConst: isConst)..fileEqualsOffset = equalsCharOffset); |
+ isConst: isConst, |
+ charOffset: equalsCharOffset); |
+ _typeInferrer.finishVariableDeclaration( |
+ currentLocalVariableType, initializer, variable); |
+ push(variable); |
} |
@override |
@@ -1022,7 +1039,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void endBlock(int count, Token beginToken, Token endToken) { |
debugEvent("Block"); |
- Block block = popBlock(count, beginToken.charOffset); |
+ ShadowBlock block = popBlock(count, beginToken.charOffset); |
exitLocalScope(); |
push(block); |
} |
@@ -1030,7 +1047,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void handleAssignmentExpression(Token token) { |
debugEvent("AssignmentExpression"); |
- Expression value = popForValue(); |
+ Expression value = popForValue() as Expression; |
var accessor = pop(); |
if (accessor is TypeDeclarationBuilder) { |
push(wrapInvalid(new TypeLiteral( |
@@ -1069,7 +1086,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
int updateExpressionCount, Token endToken) { |
debugEvent("ForStatement"); |
Statement body = popStatement(); |
- List<Expression> updates = popListForEffect(updateExpressionCount); |
+ List<Expression> updates = |
+ popListForEffect(updateExpressionCount) as List<Expression>; |
Statement conditionStatement = popStatement(); |
Expression condition = null; |
if (conditionStatement is ExpressionStatement) { |
@@ -1117,8 +1135,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void endAwaitExpression(Token beginToken, Token endToken) { |
debugEvent("AwaitExpression"); |
- push( |
- new AwaitExpression(popForValue())..fileOffset = beginToken.charOffset); |
+ push(new AwaitExpression(popForValue() as Expression) |
+ ..fileOffset = beginToken.charOffset); |
} |
@override |
@@ -1131,20 +1149,19 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
void handleLiteralList( |
int count, Token beginToken, Token constKeyword, Token endToken) { |
debugEvent("LiteralList"); |
- List<Expression> expressions = popListForValue(count); |
+ List<ShadowExpression> expressions = popListForValue(count); |
List<DartType> typeArguments = pop(); |
- DartType typeArgument = const DynamicType(); |
+ DartType typeArgument; |
if (typeArguments != null) { |
typeArgument = typeArguments.first; |
if (typeArguments.length > 1) { |
- typeArgument = const DynamicType(); |
+ typeArgument = null; |
warning( |
"Too many type arguments on List literal.", beginToken.charOffset); |
} |
} |
- push(new ListLiteral(expressions, |
- typeArgument: typeArgument, isConst: constKeyword != null) |
- ..fileOffset = constKeyword?.charOffset ?? beginToken.charOffset); |
+ push(_ast.listLiteral(expressions, typeArgument, constKeyword != null, |
+ constKeyword?.charOffset ?? beginToken.charOffset)); |
} |
@override |
@@ -1165,7 +1182,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void handleLiteralNull(Token token) { |
debugEvent("LiteralNull"); |
- push(new NullLiteral()..fileOffset = token.charOffset); |
+ push(_ast.nullLiteral(token.charOffset)); |
} |
@override |
@@ -1195,8 +1212,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void endLiteralMapEntry(Token colon, Token endToken) { |
debugEvent("LiteralMapEntry"); |
- Expression value = popForValue(); |
- Expression key = popForValue(); |
+ Expression value = popForValue() as Expression; |
+ Expression key = popForValue() as Expression; |
push(new MapEntry(key, value)); |
} |
@@ -1336,7 +1353,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
void handleAsOperator(Token operator, Token endToken) { |
debugEvent("AsOperator"); |
DartType type = pop(); |
- Expression expression = popForValue(); |
+ Expression expression = popForValue() as Expression; |
push(new AsExpression(expression, type)..fileOffset = operator.charOffset); |
} |
@@ -1344,7 +1361,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
void handleIsOperator(Token operator, Token not, Token endToken) { |
debugEvent("IsOperator"); |
DartType type = pop(); |
- Expression expression = popForValue(); |
+ Expression expression = popForValue() as Expression; |
expression = new IsExpression(expression, type) |
..fileOffset = operator.charOffset; |
if (not != null) { |
@@ -1356,9 +1373,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void handleConditionalExpression(Token question, Token colon) { |
debugEvent("ConditionalExpression"); |
- Expression elseExpression = popForValue(); |
- Expression thenExpression = popForValue(); |
- Expression condition = popForValue(); |
+ Expression elseExpression = popForValue() as Expression; |
+ Expression thenExpression = popForValue() as Expression; |
+ Expression condition = popForValue() as Expression; |
push(new ConditionalExpression( |
condition, thenExpression, elseExpression, const DynamicType())); |
} |
@@ -1366,7 +1383,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void endThrowExpression(Token throwToken, Token endToken) { |
debugEvent("ThrowExpression"); |
- Expression expression = popForValue(); |
+ Expression expression = popForValue() as Expression; |
push(new Throw(expression)..fileOffset = throwToken.charOffset); |
} |
@@ -1387,7 +1404,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
DartType type = pop(); |
pop(); // Modifiers. |
ignore(Unhandled.Metadata); |
- VariableDeclaration variable; |
+ ShadowVariableDeclaration variable; |
if (!inCatchClause && functionNestingLevel == 0) { |
dynamic builder = formalParameterScope.lookup(name.name, charOffset, uri); |
if (builder == null) { |
@@ -1400,7 +1417,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
} |
} else if (thisKeyword == null) { |
variable = builder.build(library); |
- variable.initializer = name.initializer; |
+ (variable as VariableDeclaration).initializer = name.initializer; |
} else if (builder.isField && builder.parent == classBuilder) { |
FieldBuilder field = builder; |
if (type != null) { |
@@ -1408,16 +1425,19 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
thisKeyword.charOffset); |
} |
type = field.target.type ?? const DynamicType(); |
- variable = new VariableDeclaration(name.name, |
- type: type, initializer: name.initializer); |
+ variable = _ast.variableDeclaration(name.name, |
+ type: type, |
+ initializer: name.initializer as ShadowExpression, |
+ charOffset: name.fileOffset); |
} else { |
addCompileTimeError( |
name.fileOffset, "'${name.name}' isn't a field in this class."); |
} |
} |
- variable ??= new VariableDeclaration(name.name, |
- type: type ?? const DynamicType(), |
- initializer: name.initializer)..fileOffset = name.fileOffset; |
+ variable ??= _ast.variableDeclaration(name.name, |
+ type: type, |
+ initializer: name.initializer as ShadowExpression, |
+ charOffset: name.fileOffset); |
push(variable); |
} |
@@ -1456,7 +1476,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void handleValuedFormalParameter(Token equals, Token token) { |
debugEvent("ValuedFormalParameter"); |
- Expression initializer = popForValue(); |
+ Expression initializer = popForValue() as Expression; |
Identifier name = pop(); |
push(new InitializedIdentifier(name.name, initializer)); |
} |
@@ -1554,14 +1574,14 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
void handleIndexedExpression( |
Token openCurlyBracket, Token closeCurlyBracket) { |
debugEvent("IndexedExpression"); |
- Expression index = popForValue(); |
+ Expression index = popForValue() as Expression; |
var receiver = pop(); |
if (receiver is ThisAccessor && receiver.isSuper) { |
push(new SuperIndexAccessor(this, receiver.charOffset, index, |
lookupSuperMember(indexGetName), lookupSuperMember(indexSetName))); |
} else { |
push(IndexAccessor.make(this, openCurlyBracket.charOffset, |
- toValue(receiver), index, null, null)); |
+ toValue(receiver) as Expression, index, null, null)); |
} |
} |
@@ -1570,7 +1590,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
debugEvent("UnaryPrefixExpression"); |
var receiver = pop(); |
if (optional("!", token)) { |
- push(new Not(toValue(receiver))); |
+ push(new Not(toValue(receiver) as Expression)); |
} else { |
String operator = token.stringValue; |
if (optional("-", token)) { |
@@ -1583,8 +1603,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
new Arguments.empty(), |
token.charOffset))); |
} else { |
- push(buildMethodInvocation(toValue(receiver), new Name(operator), |
- new Arguments.empty(), token.charOffset)); |
+ push(buildMethodInvocation(toValue(receiver) as Expression, |
+ new Name(operator), new Arguments.empty(), token.charOffset)); |
} |
} |
} |
@@ -1603,7 +1623,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
push(accessor.buildPrefixIncrement( |
incrementOperator(token), token.charOffset)); |
} else { |
- push(wrapInvalid(toValue(accessor))); |
+ push(wrapInvalid(toValue(accessor) as Expression)); |
} |
} |
@@ -1615,7 +1635,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
push(new DelayedPostfixIncrement( |
this, token.charOffset, accessor, incrementOperator(token), null)); |
} else { |
- push(wrapInvalid(toValue(accessor))); |
+ push(wrapInvalid(toValue(accessor) as Expression)); |
} |
} |
@@ -1683,7 +1703,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
typeParameters = target.enclosingClass.typeParameters; |
} |
if (!checkArguments(target.function, arguments, typeParameters)) { |
- return throwNoSuchMethodError(target.name.name, arguments, charOffset); |
+ return throwNoSuchMethodError(target.name.name, arguments, charOffset) |
+ as Expression; |
} |
if (target is Constructor) { |
return new ConstructorInvocation(target, arguments) |
@@ -1844,7 +1865,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void handleNamedArgument(Token colon) { |
debugEvent("NamedArgument"); |
- Expression value = popForValue(); |
+ Expression value = popForValue() as Expression; |
Identifier identifier = pop(); |
push(new NamedExpression(identifier.name, value)); |
} |
@@ -1863,7 +1884,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
enterLocalScope(); |
} |
- void enterFunction() { |
+ void enterFunction(bool isNamed) { |
debugEvent("enterFunction"); |
functionNestingLevel++; |
push(switchScope ?? NullValue.SwitchScope); |
@@ -1879,13 +1900,13 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void beginFunction(Token token) { |
debugEvent("beginFunction"); |
- enterFunction(); |
+ enterFunction(true); |
} |
@override |
void beginUnnamedFunction(Token token) { |
debugEvent("beginUnnamedFunction"); |
- enterFunction(); |
+ enterFunction(false); |
} |
@override |
@@ -1931,14 +1952,15 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
typeParameters: typeParameters, asyncMarker: asyncModifier) |
..fileOffset = beginToken.charOffset |
..fileEndOffset = token.charOffset); |
- push(new FunctionExpression(function)..fileOffset = beginToken.charOffset); |
+ push(new KernelFunctionExpression(function) |
+ ..fileOffset = beginToken.charOffset); |
} |
@override |
void endDoWhileStatement( |
Token doKeyword, Token whileKeyword, Token endToken) { |
debugEvent("DoWhileStatement"); |
- Expression condition = popForValue(); |
+ Expression condition = popForValue() as Expression; |
Statement body = popStatement(); |
JumpTarget continueTarget = exitContinueTarget(); |
JumpTarget breakTarget = exitBreakTarget(); |
@@ -1962,7 +1984,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
@override |
void endForInExpression(Token token) { |
debugEvent("ForInExpression"); |
- Expression expression = popForValue(); |
+ Expression expression = popForValue() as Expression; |
exitLocalScope(); |
push(expression ?? NullValue.Expression); |
} |
@@ -1972,7 +1994,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
Token inKeyword, Token rightParenthesis, Token endToken) { |
debugEvent("ForIn"); |
Statement body = popStatement(); |
- Expression expression = popForValue(); |
+ Expression expression = popForValue() as Expression; |
var lvalue = pop(); |
exitLocalScope(); |
JumpTarget continueTarget = exitContinueTarget(); |
@@ -2002,7 +2024,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
body); |
} else { |
variable = new VariableDeclaration.forValue(buildCompileTimeError( |
- "Expected lvalue, but got ${lvalue}", forToken.next.next.charOffset)); |
+ "Expected lvalue, but got ${lvalue}", |
+ forToken.next.next.charOffset) as Expression); |
} |
Statement result = new ForInStatement(variable, expression, body, |
isAsync: awaitToken != null)..fileOffset = body.fileOffset; |
@@ -2071,7 +2094,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
void endWhileStatement(Token whileKeyword, Token endToken) { |
debugEvent("WhileStatement"); |
Statement body = popStatement(); |
- Expression condition = popForValue(); |
+ Expression condition = popForValue() as Expression; |
JumpTarget continueTarget = exitContinueTarget(); |
JumpTarget breakTarget = exitBreakTarget(); |
if (continueTarget.hasUsers) { |
@@ -2096,16 +2119,16 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
void handleAssertStatement(Token assertKeyword, Token leftParenthesis, |
Token commaToken, Token rightParenthesis, Token semicolonToken) { |
debugEvent("AssertStatement"); |
- Expression message = popForValueIfNotNull(commaToken); |
- Expression condition = popForValue(); |
+ Expression message = popForValueIfNotNull(commaToken) as Expression; |
+ Expression condition = popForValue() as Expression; |
push(new AssertStatement(condition, message)); |
} |
@override |
void endYieldStatement(Token yieldToken, Token starToken, Token endToken) { |
debugEvent("YieldStatement"); |
- push(new YieldStatement(popForValue(), isYieldStar: starToken != null) |
- ..fileOffset = yieldToken.charOffset); |
+ push(new YieldStatement(popForValue() as Expression, |
+ isYieldStar: starToken != null)..fileOffset = yieldToken.charOffset); |
} |
@override |
@@ -2127,7 +2150,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
if (labelOrExpression is Label) { |
labels.add(labelOrExpression); |
} else { |
- expressions.add(toValue(labelOrExpression)); |
+ expressions.add(toValue(labelOrExpression) as Expression); |
} |
} |
} |
@@ -2154,7 +2177,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
Token firstToken, |
Token endToken) { |
debugEvent("SwitchCase"); |
- Block block = popBlock(statementCount, firstToken.charOffset); |
+ Block block = popBlock(statementCount, firstToken.charOffset) as Block; |
exitLocalScope(); |
List<Label> labels = pop(); |
List<Expression> expressions = pop(); |
@@ -2192,7 +2215,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
JumpTarget target = exitBreakTarget(); |
exitSwitchScope(); |
exitLocalScope(); |
- Expression expression = popForValue(); |
+ Expression expression = popForValue() as Expression; |
Statement result = new SwitchStatement(expression, cases); |
if (target.hasUsers) { |
result = new LabeledStatement(result); |
@@ -2345,27 +2368,30 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
} |
@override |
- Expression buildCompileTimeError(error, [int charOffset = -1]) { |
+ ShadowExpression buildCompileTimeError(error, [int charOffset = -1]) { |
addCompileTimeError(charOffset, error); |
String message = formatUnexpected(uri, charOffset, error); |
Builder constructor = library.loader.getCompileTimeError(); |
return new Throw(buildStaticInvocation(constructor.target, |
- new Arguments(<Expression>[new StringLiteral(message)]), |
- isConst: false)); // TODO(ahe): Make this const. |
+ new Arguments(<Expression>[new StringLiteral(message)]), |
+ isConst: false) as Expression) |
+ as ShadowExpression; // TODO(ahe): Make this const. |
} |
Statement buildCompileTimeErrorStatement(error, [int charOffset = -1]) { |
- return new ExpressionStatement(buildCompileTimeError(error, charOffset)); |
+ return new ExpressionStatement( |
+ buildCompileTimeError(error, charOffset) as Expression); |
} |
@override |
Initializer buildCompileTimeErrorIntializer(error, [int charOffset = -1]) { |
return new LocalInitializer(new VariableDeclaration.forValue( |
- buildCompileTimeError(error, charOffset))); |
+ buildCompileTimeError(error, charOffset) as Expression)); |
} |
@override |
- Expression buildProblemExpression(ProblemBuilder builder, int charOffset) { |
+ ShadowExpression buildProblemExpression( |
+ ProblemBuilder builder, int charOffset) { |
return buildCompileTimeError(builder.message, charOffset); |
} |
@@ -2500,9 +2526,9 @@ abstract class ContextAccessor extends BuilderAccessor { |
return internalError("Unhandled: ${runtimeType}", uri, charOffset); |
} |
- Expression buildSimpleRead(); |
+ ShadowExpression buildSimpleRead(); |
- Expression buildForEffect(); |
+ ShadowExpression buildForEffect(); |
Expression buildAssignment(Expression value, {bool voidContext: false}) { |
return makeInvalidWrite(value); |
@@ -2533,7 +2559,8 @@ abstract class ContextAccessor extends BuilderAccessor { |
Expression makeInvalidWrite(Expression value) { |
return helper.buildCompileTimeError( |
- "Can't be used as left-hand side of assignment.", charOffset); |
+ "Can't be used as left-hand side of assignment.", charOffset) |
+ as Expression; |
} |
} |
@@ -2546,12 +2573,12 @@ class DelayedAssignment extends ContextAccessor { |
BuilderAccessor accessor, this.value, this.assignmentOperator) |
: super(helper, charOffset, accessor); |
- Expression buildSimpleRead() { |
- return handleAssignment(false); |
+ ShadowExpression buildSimpleRead() { |
+ return handleAssignment(false) as ShadowExpression; |
} |
- Expression buildForEffect() { |
- return handleAssignment(true); |
+ ShadowExpression buildForEffect() { |
+ return handleAssignment(true) as ShadowExpression; |
} |
Expression handleAssignment(bool voidContext) { |
@@ -2624,14 +2651,16 @@ class DelayedPostfixIncrement extends ContextAccessor { |
BuilderAccessor accessor, this.binaryOperator, this.interfaceTarget) |
: super(helper, charOffset, accessor); |
- Expression buildSimpleRead() { |
+ ShadowExpression buildSimpleRead() { |
return accessor.buildPostfixIncrement(binaryOperator, charOffset, |
- voidContext: false, interfaceTarget: interfaceTarget); |
+ voidContext: false, |
+ interfaceTarget: interfaceTarget) as ShadowExpression; |
} |
- Expression buildForEffect() { |
+ ShadowExpression buildForEffect() { |
return accessor.buildPostfixIncrement(binaryOperator, charOffset, |
- voidContext: true, interfaceTarget: interfaceTarget); |
+ voidContext: true, |
+ interfaceTarget: interfaceTarget) as ShadowExpression; |
} |
} |