| 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;
|
| }
|
| }
|
|
|
|
|