Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(380)

Unified Diff: sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_to_frontend_ast.dart

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_to_frontend_ast.dart
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_to_frontend_ast.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_to_frontend_ast.dart
deleted file mode 100644
index d314f54ebf8f700b5abfa9ae705b4c2863a393f7..0000000000000000000000000000000000000000
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_to_frontend_ast.dart
+++ /dev/null
@@ -1,1217 +0,0 @@
-// Copyright (c) 2014, 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.
-
-library dart_tree_printer;
-
-import '../constants/values.dart' as values;
-import '../dart_types.dart' as types;
-import '../dart2jslib.dart' as dart2js;
-import '../elements/elements.dart' as elements;
-import '../tree/tree.dart' as tree;
-import '../scanner/scannerlib.dart';
-import '../util/util.dart';
-import 'backend_ast_nodes.dart';
-import 'backend_ast_emitter.dart' show createTypeAnnotation;
-
-/// Translates the backend AST to Dart frontend AST.
-tree.FunctionExpression emit(dart2js.TreeElementMapping treeElements,
- Node definition) {
- return new TreePrinter(treeElements).makeExpression(definition);
-}
-
-/// If true, the unparser will insert a coment in front of every function
-/// it emits. This helps indicate which functions were translated by the new
-/// backend.
-bool INSERT_NEW_BACKEND_COMMENT =
- const bool.fromEnvironment('USE_NEW_BACKEND', defaultValue: false);
-
-/// Converts backend ASTs to frontend ASTs.
-class TreePrinter {
- dart2js.TreeElementMapping treeElements;
-
- TreePrinter([this.treeElements]);
-
- void setElement(tree.Node node, elements.Element element, source) {
- if (treeElements != null) {
- if (element == null) {
- throw "Missing element from ${source}";
- }
- treeElements[node] = element;
- }
- }
-
- void setType(tree.Node node, types.DartType type, source) {
- if (treeElements != null) {
- if (type == null) {
- throw "Missing type from ${source}";
- }
- treeElements.setType(node, type);
- }
- }
-
- // Group tokens: () [] {} <>
- static BeginGroupToken makeGroup(PrecedenceInfo open, PrecedenceInfo close) {
- BeginGroupToken openTok = new BeginGroupToken(open, -1);
- openTok.endGroup = new SymbolToken(close, -1);
- return openTok;
- }
-
- final BeginGroupToken openParen = makeGroup(OPEN_PAREN_INFO,
- CLOSE_PAREN_INFO);
- final BeginGroupToken openBrace = makeGroup(OPEN_CURLY_BRACKET_INFO,
- CLOSE_CURLY_BRACKET_INFO);
- final BeginGroupToken openBracket = makeGroup(OPEN_SQUARE_BRACKET_INFO,
- CLOSE_SQUARE_BRACKET_INFO);
- final BeginGroupToken lt = makeGroup(LT_INFO, GT_INFO);
-
- Token get closeParen => openParen.endGroup;
- Token get closeBrace => openBrace.endGroup;
- Token get closeBracket => openBracket.endGroup;
- Token get gt => lt.endGroup;
-
- // Symbol tokens
- final Token semicolon = new SymbolToken(SEMICOLON_INFO, -1);
- final Token indexToken = new SymbolToken(INDEX_INFO, -1); // "[]"
- final Token question = new SymbolToken(QUESTION_INFO, -1);
- final Token colon = new SymbolToken(COLON_INFO, -1);
- final Token hash = new SymbolToken(HASH_INFO, -1);
- final Token bang = new SymbolToken(BANG_INFO, -1);
- final Token eq = new SymbolToken(EQ_INFO, -1);
-
- // Keyword tokens
- static Token makeIdToken(String text) {
- return new StringToken.fromString(IDENTIFIER_INFO, text, -1);
- }
- final Token newToken = makeIdToken('new');
- final Token constToken = makeIdToken('const');
- final Token throwToken = makeIdToken('throw');
- final Token rethrowToken = makeIdToken('rethrow');
- final Token breakToken = makeIdToken('break');
- final Token continueToken = makeIdToken('continue');
- final Token doToken = makeIdToken('do');
- final Token whileToken = makeIdToken('while');
- final Token ifToken = makeIdToken('if');
- final Token elseToken = makeIdToken('else');
- final Token awaitToken = makeIdToken('await');
- final Token forToken = makeIdToken('for');
- final Token inToken = makeIdToken('in');
- final Token returnToken = makeIdToken('return');
- final Token switchToken = makeIdToken('switch');
- final Token caseToken = makeIdToken('case');
- final Token defaultToken = makeIdToken('default');
- final Token tryToken = makeIdToken('try');
- final Token catchToken = makeIdToken('catch');
- final Token onToken = makeIdToken('on');
- final Token finallyToken = makeIdToken('finally');
- final Token getToken = makeIdToken('get');
- final Token setToken = makeIdToken('set');
- final Token classToken = makeIdToken('class');
- final Token extendsToken = makeIdToken('extends');
- final Token withToken = makeIdToken('with');
- final Token implementsToken = makeIdToken('implements');
-
- static tree.Identifier makeIdentifier(String name) {
- return new tree.Identifier(
- new StringToken.fromString(IDENTIFIER_INFO, name, -1));
- }
-
- static tree.Operator makeOperator(String name) {
- return new tree.Operator(
- new StringToken.fromString(IDENTIFIER_INFO, name, -1));
- }
-
- // Utilities for creating NodeLists
- Link<tree.Node> makeLink(Iterable<tree.Node> nodes) {
- LinkBuilder builder = new LinkBuilder();
- for (tree.Node node in nodes) {
- builder.addLast(node);
- }
- return builder.toLink();
- }
-
- tree.NodeList blankList() {
- return new tree.NodeList(null, makeLink([]), null, '');
- }
- tree.NodeList singleton(tree.Node node) {
- return new tree.NodeList(null, makeLink([node]), null, '');
- }
- tree.NodeList makeList(String delimiter,
- Iterable<tree.Node> nodes,
- { Token open,
- Token close }) {
- return new tree.NodeList(open, makeLink(nodes), close, delimiter);
- }
- tree.NodeList parenList(String delimiter, Iterable<tree.Node> nodes) {
- return makeList(delimiter, nodes, open: openParen, close: closeParen);
- }
- tree.NodeList bracketList(String delimiter, Iterable<tree.Node> nodes) {
- return makeList(delimiter, nodes, open: openBracket, close: closeBracket);
- }
- tree.NodeList braceList(String delimiter, Iterable<tree.Node> nodes) {
- return makeList(delimiter, nodes, open: openBrace, close: closeBrace);
- }
- tree.NodeList argList(Iterable<tree.Node> nodes) {
- return parenList(',', nodes);
- }
- tree.NodeList typeArgList(Iterable<tree.Node> nodes) {
- return makeList(',', nodes, open: lt, close: gt);
- }
-
- /// Converts a qualified name into nested Sends.
- tree.Node makeName(String name) {
- if (name == null) {
- return null;
- }
- List<String> names = name.split('.').toList(growable:false);
- tree.Node node = makeIdentifier(names[0]);
- for (int i = 1; i < names.length; i++) {
- node = new tree.Send(node, makeIdentifier(names[i]));
- }
- return node;
- }
-
- static Token assignmentToken(String operatorName) {
- switch (operatorName) {
- case '=': return new SymbolToken(EQ_INFO, -1);
- case '+=': return new SymbolToken(PLUS_EQ_INFO, -1);
- case '-=': return new SymbolToken(MINUS_EQ_INFO, -1);
- case '*=': return new SymbolToken(STAR_EQ_INFO, -1);
- case '/=': return new SymbolToken(SLASH_EQ_INFO, -1);
- case '~/=': return new SymbolToken(TILDE_SLASH_EQ_INFO, -1);
- case '%=': return new SymbolToken(PERCENT_EQ_INFO, -1);
- case '&=': return new SymbolToken(AMPERSAND_EQ_INFO, -1);
- case '^=': return new SymbolToken(CARET_EQ_INFO, -1);
- case '|=': return new SymbolToken(BAR_EQ_INFO, -1);
- case '>>=': return new SymbolToken(GT_GT_EQ_INFO, -1);
- case '<<=': return new SymbolToken(LT_LT_EQ_INFO, -1);
- default:
- throw "Unrecognized assignment operator: $operatorName";
- }
- }
-
- static Token binopToken(String operatorName) {
- switch (operatorName) {
- case '+': return new SymbolToken(PLUS_INFO, -1);
- case '-': return new SymbolToken(MINUS_INFO, -1);
- case '*': return new SymbolToken(STAR_INFO, -1);
- case '/': return new SymbolToken(SLASH_INFO, -1);
- case '~/': return new SymbolToken(TILDE_SLASH_INFO, -1);
- case '%': return new SymbolToken(PERCENT_INFO, -1);
- case '&': return new SymbolToken(AMPERSAND_INFO, -1);
- case '^': return new SymbolToken(CARET_INFO, -1);
- case '|': return new SymbolToken(BAR_INFO, -1);
- case '>>': return new SymbolToken(GT_GT_INFO, -1);
- case '<<': return new SymbolToken(LT_LT_INFO, -1);
- case '==': return new SymbolToken(EQ_EQ_INFO, -1);
- case '!=': return new SymbolToken(BANG_EQ_INFO, -1);
- case '>': return new SymbolToken(GT_INFO, -1);
- case '>=': return new SymbolToken(GT_EQ_INFO, -1);
- case '<': return new SymbolToken(LT_INFO, -1);
- case '<=': return new SymbolToken(LT_EQ_INFO, -1);
- case '&&': return new SymbolToken(AMPERSAND_AMPERSAND_INFO, -1);
- case '||': return new SymbolToken(BAR_BAR_INFO, -1);
- default:
- throw "Unrecognized binary operator: $operatorName";
- }
- }
-
- static Token incrementToken(String operatorName) {
- switch (operatorName) {
- case '++': return new SymbolToken(PLUS_PLUS_INFO, -1);
- case '--': return new SymbolToken(MINUS_MINUS_INFO, -1);
- default:
- throw "Unrecognized increment operator: $operatorName";
- }
- }
-
- static Token typeOpToken(String operatorName) {
- switch (operatorName) { // "is!" is not an operator in the frontend AST.
- case 'is': return new SymbolToken(IS_INFO, -1);
- case 'as': return new SymbolToken(AS_INFO, -1);
- default:
- throw 'Unrecognized type operator: $operatorName';
- }
- }
-
- Token unopToken(String operatorName) {
- switch (operatorName) {
- case '-': return new SymbolToken(MINUS_INFO, -1);
- case '~': return new SymbolToken(TILDE_INFO, -1);
- case '!': return bang;
- default:
- throw "Unrecognized unary operator: $operatorName";
- }
- }
-
- tree.Node makeStaticReceiver(elements.Element element) {
- if (treeElements == null) return null;
- if (element.isStatic) {
- elements.ClassElement enclosingClass = element.enclosingClass;
- tree.Send send = new tree.Send(
- null,
- makeIdentifier(enclosingClass.name));
- treeElements[send] = enclosingClass;
- return send;
- } else {
- return null;
- }
- }
-
- tree.Node makeArgument(Argument arg) {
- if (arg is Expression) {
- return makeExpression(arg);
- } else if (arg is NamedArgument) {
- return new tree.NamedArgument(
- makeIdentifier(arg.name),
- colon,
- makeExpression(arg.expression));
- } else {
- throw "Unrecognized argument type: ${arg}";
- }
- }
-
- tree.Node makeExpression(Expression exp) {
- return makeExp(exp, EXPRESSION);
- }
-
- /// Converts [exp] to a [tree.Node] that unparses to an expression with
- /// a precedence level of at least [minPrecedence]. The expression will be
- /// wrapped in a parenthesis if necessary.
- tree.Node makeExp(Receiver exp, int minPrecedence, {bool beginStmt: false}) {
- tree.Node result;
- int precedence;
- bool needParen = false;
- if (exp is SuperReceiver) {
- precedence = CALLEE;
- result = makeIdentifier('super');
- } else if (exp is Assignment) {
- Expression left = exp.left;
- tree.Node receiver;
- tree.Node selector;
- tree.NodeList arguments;
- elements.Element element;
- if (left is Identifier) {
- receiver = makeStaticReceiver(left.element);
- selector = makeIdentifier(left.name);
- arguments = singleton(makeExpression(exp.right));
- element = left.element;
- } else if (left is FieldExpression) {
- receiver = makeExp(left.object, PRIMARY, beginStmt: beginStmt);
- selector = makeIdentifier(left.fieldName);
- arguments = singleton(makeExpression(exp.right));
- } else if (left is IndexExpression) {
- receiver = makeExp(left.object, PRIMARY, beginStmt: beginStmt);
- selector = new tree.Operator(indexToken);
- arguments = bracketList(',',
- [makeExpression(left.index), makeExpression(exp.right)]);
- } else {
- throw "Unexpected left-hand side of assignment: ${left}";
- }
- tree.Operator op = new tree.Operator(assignmentToken(exp.operator));
- result = new tree.SendSet(receiver, selector, op, arguments);
- if (left is Identifier) {
- setElement(result, element, exp);
- }
- precedence = EXPRESSION;
- } else if (exp is BinaryOperator) {
- precedence = BINARY_PRECEDENCE[exp.operator];
- int deltaLeft = isAssociativeBinaryOperator(precedence) ? 0 : 1;
- result = new tree.Send(
- makeExp(exp.left, precedence + deltaLeft, beginStmt: beginStmt),
- new tree.Operator(binopToken(exp.operator)),
- singleton(makeExp(exp.right, precedence + 1)));
- } else if (exp is CallFunction) {
- precedence = CALLEE;
- tree.Node selector;
- Expression callee = exp.callee;
- elements.Element element;
- tree.Node receiver;
- if (callee is Identifier) {
- receiver = makeStaticReceiver(callee.element);
- selector = makeIdentifier(callee.name);
- element = callee.element;
- } else {
- selector = makeExp(callee, CALLEE, beginStmt: beginStmt);
- }
- result = new tree.Send(
- receiver,
- selector,
- argList(exp.arguments.map(makeArgument)));
- if (callee is Identifier) {
- setElement(result, element, exp);
- }
- } else if (exp is CallMethod) {
- precedence = CALLEE;
- tree.Node receiver = exp.object is This
- ? null
- : makeExp(exp.object, PRIMARY, beginStmt: beginStmt);
- result = new tree.Send(
- receiver,
- makeIdentifier(exp.methodName),
- argList(exp.arguments.map(makeArgument)));
- } else if (exp is CallNew) {
- precedence = CALLEE;
- tree.Node selector = makeName(exp.type.name);
- if (exp.type.typeArguments.length > 0) {
- selector = new tree.TypeAnnotation(
- selector,
- typeArgList(exp.type.typeArguments.map(makeType)));
- setType(selector, exp.dartType, exp);
- }
- if (exp.constructorName != null) {
- selector = new tree.Send(
- selector,
- makeIdentifier(exp.constructorName));
- }
- tree.Send send = new tree.Send(
- null,
- selector,
- argList(exp.arguments.map(makeArgument)));
- result = new tree.NewExpression(
- exp.isConst ? constToken : newToken,
- send);
- setType(result, exp.dartType, exp);
- setElement(send, exp.constructor, exp);
- } else if (exp is CallStatic) {
- precedence = CALLEE;
- result = new tree.Send(
- makeStaticReceiver(exp.element),
- makeIdentifier(exp.methodName),
- argList(exp.arguments.map(makeArgument)));
- setElement(result, exp.element, exp);
- } else if (exp is Conditional) {
- precedence = CONDITIONAL;
- result = new tree.Conditional(
- makeExp(exp.condition, LOGICAL_OR, beginStmt: beginStmt),
- makeExp(exp.thenExpression, EXPRESSION),
- makeExp(exp.elseExpression, EXPRESSION),
- question,
- colon);
- } else if (exp is FieldExpression) {
- precedence = PRIMARY;
- tree.Node receiver = exp.object is This
- ? null
- : makeExp(exp.object, PRIMARY, beginStmt: beginStmt);
- result = new tree.Send(receiver, makeIdentifier(exp.fieldName));
- } else if (exp is FunctionExpression) {
- precedence = PRIMARY;
- if (beginStmt && exp.name != null) {
- needParen = true; // Do not mistake for function declaration.
- }
- Token getOrSet = exp.isGetter
- ? getToken
- : exp.isSetter
- ? setToken
- : null;
- tree.NodeList parameters = exp.isGetter
- ? makeList("", [])
- : makeParameters(exp.parameters);
- tree.Node body = makeFunctionBody(exp.body);
- result = new tree.FunctionExpression(
- functionName(exp),
- parameters,
- body,
- exp.returnType == null || exp.element.isConstructor
- ? null
- : makeType(exp.returnType),
- makeFunctionModifiers(exp),
- null, // initializers
- getOrSet, // get/set
- null); // async modifier
- setElement(result, exp.element, exp);
- } else if (exp is Identifier) {
- precedence = CALLEE;
- result = new tree.Send(
- makeStaticReceiver(exp.element),
- makeIdentifier(exp.name));
- setElement(result, exp.element, exp);
- } else if (exp is Increment) {
- Expression lvalue = exp.expression;
- tree.Node receiver;
- tree.Node selector;
- tree.Node argument;
- bool innerBeginStmt = beginStmt && !exp.isPrefix;
- if (lvalue is Identifier) {
- receiver = makeStaticReceiver(lvalue.element);
- selector = makeIdentifier(lvalue.name);
- } else if (lvalue is FieldExpression) {
- receiver = makeExp(lvalue.object, PRIMARY, beginStmt: innerBeginStmt);
- selector = makeIdentifier(lvalue.fieldName);
- } else if (lvalue is IndexExpression) {
- receiver = makeExp(lvalue.object, PRIMARY, beginStmt: innerBeginStmt);
- selector = new tree.Operator(indexToken);
- argument = makeExpression(lvalue.index);
- } else {
- throw "Unrecognized left-hand side: ${lvalue}";
- }
- tree.Operator op = new tree.Operator(incrementToken(exp.operator));
- if (exp.isPrefix) {
- precedence = UNARY;
- result = new tree.SendSet.prefix(receiver, selector, op, argument);
- } else {
- precedence = POSTFIX_INCREMENT;
- result = new tree.SendSet.postfix(receiver, selector, op, argument);
- }
- if (lvalue is Identifier) {
- setElement(result, lvalue.element, exp);
- }
- } else if (exp is IndexExpression) {
- precedence = CALLEE;
- result = new tree.Send(
- makeExp(exp.object, PRIMARY, beginStmt: beginStmt),
- new tree.Operator(indexToken),
- bracketList(',', [makeExpression(exp.index)]));
- } else if (exp is Literal) {
- precedence = CALLEE;
- values.PrimitiveConstantValue value = exp.value;
- Token tok = new StringToken.fromString(
- STRING_INFO, '${value.primitiveValue}', -1);
- if (value.isString) {
- result = unparseStringLiteral(exp);
- } else if (value.isInt) {
- result = new tree.LiteralInt(tok, null);
- } else if (value.isDouble) {
- if (value.primitiveValue == double.INFINITY) {
- precedence = MULTIPLICATIVE;
- tok = new StringToken.fromString(STRING_INFO, '1/0.0', -1);
- } else if (value.primitiveValue == double.NEGATIVE_INFINITY) {
- precedence = MULTIPLICATIVE;
- tok = new StringToken.fromString(STRING_INFO, '-1/0.0', -1);
- } else if (value.primitiveValue.isNaN) {
- precedence = MULTIPLICATIVE;
- tok = new StringToken.fromString(STRING_INFO, '0/0.0', -1);
- }
- result = new tree.LiteralDouble(tok, null);
- } else if (value.isBool) {
- result = new tree.LiteralBool(tok, null);
- } else if (value.isNull) {
- result = new tree.LiteralNull(tok);
- } else {
- throw "Unrecognized constant: ${value}";
- }
- } else if (exp is LiteralList) {
- precedence = PRIMARY;
- tree.NodeList typeArgs = null;
- if (exp.typeArgument != null) {
- typeArgs = typeArgList([makeType(exp.typeArgument)]);
- }
- result = new tree.LiteralList(
- typeArgs,
- bracketList(',', exp.values.map(makeExpression)),
- exp.isConst ? constToken : null);
- } else if (exp is LiteralMap) {
- precedence = PRIMARY;
- if (beginStmt) {
- // The opening brace can be confused with a block statement.
- needParen = true;
- }
- tree.NodeList typeArgs = null;
- if (exp.typeArguments != null && exp.typeArguments.length > 0) {
- typeArgs = typeArgList(exp.typeArguments.map(makeType));
- }
- result = new tree.LiteralMap(
- typeArgs,
- braceList(',', exp.entries.map(makeLiteralMapEntry)),
- exp.isConst ? constToken : null);
- } else if (exp is LiteralSymbol) {
- precedence = PRIMARY;
- result = new tree.LiteralSymbol(
- hash,
- makeList('.', exp.id.split('.').map(makeIdentifier)));
- } else if (exp is LiteralType) {
- precedence = TYPE_LITERAL;
- elements.Element optionalElement = exp.type.element;
- result = new tree.Send(
- optionalElement == null ? null : makeStaticReceiver(optionalElement),
- makeIdentifier(exp.name));
- treeElements.setType(result, exp.type);
- if (optionalElement != null) { // dynamic does not have an element
- setElement(result, optionalElement, exp);
- }
- } else if (exp is ReifyTypeVar) {
- precedence = PRIMARY;
- result = new tree.Send(
- null,
- makeIdentifier(exp.name));
- setElement(result, exp.element, exp);
- setType(result, exp.element.type, exp);
- } else if (exp is StringConcat) {
- precedence = PRIMARY;
- result = unparseStringLiteral(exp);
- } else if (exp is This) {
- precedence = CALLEE;
- result = makeIdentifier('this');
- } else if (exp is Throw) {
- precedence = EXPRESSION; // ???
- result = new tree.Throw(
- makeExpression(exp.expression),
- throwToken,
- throwToken); // endToken not used by unparser
- } else if (exp is TypeOperator) {
- precedence = RELATIONAL;
- tree.Operator operator;
- tree.Node rightOperand = makeType(exp.type);
- if (exp.operator == 'is!') {
- operator = new tree.Operator(typeOpToken('is'));
- rightOperand = new tree.Send(
- rightOperand,
- new tree.Operator(bang),
- blankList());
- } else {
- operator = new tree.Operator(typeOpToken(exp.operator));
- }
- result = new tree.Send(
- makeExp(exp.expression, BITWISE_OR, beginStmt: beginStmt),
- operator,
- singleton(rightOperand));
- } else if (exp is UnaryOperator) {
- precedence = UNARY;
- result = new tree.Send.prefix(
- makeExp(exp.operand, UNARY),
- new tree.Operator(unopToken(exp.operatorName)));
- } else {
- throw "Unknown expression type: ${exp}";
- }
-
- needParen = needParen || precedence < minPrecedence;
- if (needParen) {
- result = parenthesize(result);
- }
- return result;
- }
-
- /// Creates a LiteralString with [verbatim] as the value.
- /// No (un)quoting or (un)escaping will be performed by this method.
- /// The [DartString] inside the literal will be set to null because the
- /// code emitter does not use it.
- tree.LiteralString makeVerbatimStringLiteral(String verbatim) {
- Token tok = new StringToken.fromString(STRING_INFO, verbatim, -1);
- return new tree.LiteralString(tok, null);
- }
-
- tree.LiteralMapEntry makeLiteralMapEntry(LiteralMapEntry en) {
- return new tree.LiteralMapEntry(
- makeExpression(en.key),
- colon,
- makeExpression(en.value));
- }
-
- /// A comment token to be inserted when [INSERT_NEW_BACKEND_COMMENT] is true.
- final SymbolToken newBackendComment = new SymbolToken(
- const PrecedenceInfo('/* new backend */ ', 0, OPEN_CURLY_BRACKET_TOKEN),
- -1);
-
- tree.Node makeFunctionBody(Statement stmt) {
- if (INSERT_NEW_BACKEND_COMMENT) {
- return new tree.Block(makeList('', [makeBlock(stmt)],
- open: newBackendComment));
- } else {
- return makeBlock(stmt);
- }
- }
-
- /// Produces a statement in a context where only blocks are allowed.
- tree.Node makeBlock(Statement stmt) {
- if (stmt is Block || stmt is EmptyStatement) {
- return makeStatement(stmt);
- } else {
- return new tree.Block(braceList('', [makeStatement(stmt)]));
- }
- }
-
- /// Adds the given statement to a block. If the statement itself is a block
- /// it will be flattened (if this does not change lexical scoping).
- void addBlockMember(Statement stmt, List<tree.Node> accumulator) {
- if (stmt is Block && !stmt.statements.any(Unparser.definesVariable)) {
- for (Statement innerStmt in stmt.statements) {
- addBlockMember(innerStmt, accumulator);
- }
- } else if (stmt is EmptyStatement) {
- // No need to include empty statements inside blocks
- } else {
- accumulator.add(makeStatement(stmt));
- }
- }
-
- /// True if [stmt] is equivalent to an empty statement.
- bool isEmptyStatement(Statement stmt) {
- return stmt is EmptyStatement ||
- (stmt is Block && stmt.statements.every(isEmptyStatement));
- }
-
- tree.Node makeStatement(Statement stmt, {bool shortIf: true}) {
- if (stmt is Block) {
- List<tree.Node> body = <tree.Node>[];
- for (Statement innerStmt in stmt.statements) {
- addBlockMember(innerStmt, body);
- }
- return new tree.Block(braceList('', body));
- } else if (stmt is Break) {
- return new tree.BreakStatement(
- stmt.label == null ? null : makeIdentifier(stmt.label),
- breakToken,
- semicolon);
- } else if (stmt is Continue) {
- return new tree.ContinueStatement(
- stmt.label == null ? null : makeIdentifier(stmt.label),
- continueToken,
- semicolon);
- } else if (stmt is DoWhile) {
- return new tree.DoWhile(
- makeStatement(stmt.body, shortIf: shortIf),
- parenthesize(makeExpression(stmt.condition)),
- doToken,
- whileToken,
- semicolon);
- } else if (stmt is EmptyStatement) {
- return new tree.EmptyStatement(semicolon);
- } else if (stmt is ExpressionStatement) {
- return new tree.ExpressionStatement(
- makeExp(stmt.expression, EXPRESSION, beginStmt: true),
- semicolon);
- } else if (stmt is For) {
- tree.Node initializer;
- if (stmt.initializer is VariableDeclarations) {
- initializer = makeVariableDeclarations(stmt.initializer);
- } else if (stmt.initializer is Expression) {
- initializer = makeExpression(stmt.initializer);
- } else {
- initializer = null;
- }
- tree.Node condition;
- if (stmt.condition != null) {
- condition = new tree.ExpressionStatement(
- makeExpression(stmt.condition),
- semicolon);
- } else {
- condition = new tree.EmptyStatement(semicolon);
- }
- return new tree.For(
- initializer,
- condition,
- makeList(',', stmt.updates.map(makeExpression)),
- makeStatement(stmt.body, shortIf: shortIf),
- forToken);
- } else if (stmt is ForIn) {
- tree.Node left;
- if (stmt.leftHandValue is Identifier) {
- left = makeExpression(stmt.leftHandValue);
- } else {
- left = makeVariableDeclarations(stmt.leftHandValue);
- }
- return new tree.ForIn(
- left,
- makeExpression(stmt.expression),
- makeStatement(stmt.body, shortIf: shortIf),
- awaitToken,
- forToken,
- inToken);
- } else if (stmt is FunctionDeclaration) {
- tree.FunctionExpression function = new tree.FunctionExpression(
- stmt.name != null ? makeIdentifier(stmt.name) : null,
- makeParameters(stmt.parameters),
- makeFunctionBody(stmt.body),
- stmt.returnType != null ? makeType(stmt.returnType) : null,
- makeEmptyModifiers(),
- null, // initializers
- null, // get/set
- null); // async modifier
- setElement(function, stmt.function.element, stmt);
- return new tree.FunctionDeclaration(function);
- } else if (stmt is If) {
- if (stmt.elseStatement == null || isEmptyStatement(stmt.elseStatement)) {
- tree.Node node = new tree.If(
- parenthesize(makeExpression(stmt.condition)),
- makeStatement(stmt.thenStatement),
- null, // else statement
- ifToken,
- null); // else token
- if (shortIf)
- return node;
- else
- return new tree.Block(braceList('', [node]));
- } else {
- return new tree.If(
- parenthesize(makeExpression(stmt.condition)),
- makeStatement(stmt.thenStatement, shortIf: false),
- makeStatement(stmt.elseStatement, shortIf: shortIf),
- ifToken,
- elseToken); // else token
- }
- } else if (stmt is LabeledStatement) {
- List<tree.Label> labels = [];
- Statement inner = stmt;
- while (inner is LabeledStatement) {
- LabeledStatement lbl = inner as LabeledStatement;
- labels.add(new tree.Label(makeIdentifier(lbl.label), colon));
- inner = lbl.statement;
- }
- return new tree.LabeledStatement(
- makeList('', labels),
- makeStatement(inner, shortIf: shortIf));
- } else if (stmt is Rethrow) {
- return new tree.Rethrow(rethrowToken, semicolon);
- } else if (stmt is Return) {
- return new tree.Return(
- returnToken,
- semicolon,
- stmt.expression == null ? null : makeExpression(stmt.expression));
- } else if (stmt is Switch) {
- return new tree.SwitchStatement(
- parenthesize(makeExpression(stmt.expression)),
- braceList('', stmt.cases.map(makeSwitchCase)),
- switchToken);
- } else if (stmt is Try) {
- return new tree.TryStatement(
- makeBlock(stmt.tryBlock),
- braceList('', stmt.catchBlocks.map(makeCatchBlock)),
- stmt.finallyBlock == null ? null : makeBlock(stmt.finallyBlock),
- tryToken,
- finallyToken);
- } else if (stmt is VariableDeclarations) {
- return makeVariableDeclarations(stmt, useVar: true, endToken: semicolon);
- } else if (stmt is While) {
- return new tree.While(
- parenthesize(makeExpression(stmt.condition)),
- makeStatement(stmt.body, shortIf: shortIf),
- whileToken);
- } else {
- throw "Unrecognized statement: ${stmt}";
- }
- }
-
- tree.Node makeVariableDeclaration(VariableDeclaration vd) {
- tree.Node id = makeIdentifier(vd.name);
- setElement(id, vd.element, vd);
- if (vd.initializer == null) {
- return id;
- }
- tree.Node send = new tree.SendSet(
- null,
- id,
- new tree.Operator(eq),
- singleton(makeExpression(vd.initializer)));
- setElement(send, vd.element, vd);
- return send;
- }
-
- /// If [useVar] is true, the variable definition will use `var` as modifier
- /// if no other modifiers are present.
- /// [endToken] will be used to terminate the declaration list.
- tree.Node makeVariableDeclarations(VariableDeclarations decl,
- { bool useVar: false,
- Token endToken: null }) {
- return new tree.VariableDefinitions(
- decl.type == null ? null : makeType(decl.type),
- makeVarModifiers(isConst: decl.isConst,
- isFinal: decl.isFinal,
- useVar: useVar && decl.type == null),
- makeList(',',
- decl.declarations.map(makeVariableDeclaration),
- close: endToken));
- }
-
- tree.CatchBlock makeCatchBlock(CatchBlock block) {
- List<tree.VariableDefinitions> formals = [];
- if (block.exceptionVar != null) {
- formals.add(new tree.VariableDefinitions(
- null,
- makeEmptyModifiers(),
- singleton(makeIdentifier(block.exceptionVar))));
- }
- if (block.stackVar != null) {
- formals.add(new tree.VariableDefinitions(
- null,
- makeEmptyModifiers(),
- singleton(makeIdentifier(block.stackVar))));
- }
- return new tree.CatchBlock(
- block.onType == null ? null : makeType(block.onType),
- block.exceptionVar == null ? null : argList(formals),
- makeBlock(block.body),
- block.onType == null ? null : onToken,
- block.exceptionVar == null ? null : catchToken);
- }
-
- tree.SwitchCase makeSwitchCase(SwitchCase caze) {
- if (caze.isDefaultCase) {
- return new tree.SwitchCase(
- blankList(),
- defaultToken,
- makeList('', caze.statements.map(makeStatement)),
- null); // startToken unused by unparser
- } else {
- return new tree.SwitchCase(
- makeList('', caze.expressions.map(makeCaseMatch)),
- null, // defaultKeyword,
- makeList('', caze.statements.map(makeStatement)),
- null); // startToken unused by unparser
- }
- }
-
- tree.CaseMatch makeCaseMatch(Expression exp) {
- return new tree.CaseMatch(caseToken, makeExpression(exp), colon);
- }
-
- tree.TypeAnnotation makeType(TypeAnnotation type) {
- tree.NodeList typeArgs;
- if (type.typeArguments.length > 0) {
- typeArgs = typeArgList(type.typeArguments.map(makeType));
- } else {
- typeArgs = null;
- }
- tree.TypeAnnotation result =
- new tree.TypeAnnotation(makeIdentifier(type.name), typeArgs);
- setType(result, type.dartType, type);
- return result;
- }
-
- tree.NodeList makeParameters(Parameters params) {
- List<tree.Node> nodes =
- params.requiredParameters.map(makeParameter).toList();
- if (params.hasOptionalParameters) {
- Token assign = params.hasNamedParameters ? colon : eq;
- Token open = params.hasNamedParameters ? openBrace : openBracket;
- Token close = params.hasNamedParameters ? closeBrace : closeBracket;
- Iterable<tree.Node> opt =
- params.optionalParameters.map((p) => makeParameter(p,assign));
- nodes.add(new tree.NodeList(open, makeLink(opt), close, ','));
- }
- return argList(nodes);
- }
-
- /// [assignOperator] is used for writing the default value.
- tree.Node makeParameter(Parameter param, [Token assignOperator]) {
- if (param.isFunction) {
- tree.Node definition = new tree.FunctionExpression(
- makeIdentifier(param.name),
- makeParameters(param.parameters),
- null, // body
- param.type == null ? null : makeType(param.type),
- makeEmptyModifiers(), // TODO: Function parameter modifiers?
- null, // initializers
- null, // get/set
- null); // async modifier
- if (param.element != null) {
- setElement(definition, param.element, param);
- }
- if (param.defaultValue != null) {
- return new tree.SendSet(
- null,
- definition,
- new tree.Operator(assignOperator),
- singleton(makeExpression(param.defaultValue)));
- } else {
- return new tree.VariableDefinitions(
- null,
- makeEmptyModifiers(),
- singleton(definition));
- }
- } else {
- tree.Node definition;
- if (param.defaultValue != null) {
- definition = new tree.SendSet(
- null,
- makeIdentifier(param.name),
- new tree.Operator(assignOperator),
- singleton(makeExpression(param.defaultValue)));
- } else {
- definition = makeIdentifier(param.name);
- }
- if (param.element != null) {
- setElement(definition, param.element, param);
- }
- return new tree.VariableDefinitions(
- param.type == null ? null : makeType(param.type),
- makeEmptyModifiers(), // TODO: Parameter modifiers?
- singleton(definition));
- }
- }
-
- tree.Modifiers makeEmptyModifiers() {
- return new tree.Modifiers(blankList());
- }
-
- tree.Modifiers makeModifiers({bool isStatic: false,
- bool isAbstract: false,
- bool isFactory: false,
- bool isConst: false,
- bool isFinal: false,
- bool isVar: false}) {
- List<tree.Node> nodes = [];
- if (isStatic) {
- nodes.add(makeIdentifier('static'));
- }
- if (isAbstract) {
- nodes.add(makeIdentifier('abstract'));
- }
- if (isFactory) {
- nodes.add(makeIdentifier('factory'));
- }
- if (isConst) {
- nodes.add(makeIdentifier('const'));
- }
- if (isFinal) {
- nodes.add(makeIdentifier('final'));
- }
- if (isVar) {
- nodes.add(makeIdentifier('var'));
- }
- return new tree.Modifiers(makeList('', nodes));
- }
-
- tree.Modifiers makeVarModifiers({bool isConst: false,
- bool isFinal: false,
- bool useVar: false}) {
- return makeModifiers(isConst: isConst,
- isFinal: isFinal,
- isVar: useVar && !(isConst || isFinal));
- }
-
- tree.Modifiers makeFunctionModifiers(FunctionExpression exp) {
- if (exp.element == null) return makeEmptyModifiers();
- return makeModifiers(isStatic: exp.element.isStatic,
- isFactory: exp.element.isFactoryConstructor);
- }
-
- tree.Node makeNodeForClassElement(elements.ClassElement cls) {
- if (cls.isMixinApplication) {
- return makeNamedMixinApplication(cls);
- } else {
- return makeClassNode(cls);
- }
- }
-
- /// Create a [tree.NodeList] containing the type variable declarations in
- /// [typeVaraiables.
- tree.NodeList makeTypeParameters(List<types.DartType> typeVariables) {
- if (typeVariables.isEmpty) {
- return new tree.NodeList.empty();
- } else {
- List<tree.Node> typeVariableList = <tree.Node>[];
- for (types.TypeVariableType typeVariable in typeVariables) {
- tree.Node id = makeIdentifier(typeVariable.name);
- treeElements[id] = typeVariable.element;
- tree.Node bound;
- if (!typeVariable.element.bound.isObject) {
- bound = makeType(createTypeAnnotation(typeVariable.element.bound));
- }
- tree.TypeVariable node = new tree.TypeVariable(id, bound);
- treeElements.setType(node, typeVariable);
- typeVariableList.add(node);
- }
- return makeList(',', typeVariableList, open: lt, close: gt);
- }
- }
-
- /// Create a [tree.NodeList] containing the declared interfaces.
- ///
- /// [interfaces] is from [elements.ClassElement] in reverse declaration order
- /// and it contains mixins. To produce a list of the declared interfaces only,
- /// interfaces in [mixinTypes] are omitted.
- ///
- /// [forNamedMixinApplication] is because the structure of the [tree.NodeList]
- /// differs between [tree.NamedMixinApplication] and [tree.ClassNode].
- // TODO(johnniwinther): Normalize interfaces on[tree.NamedMixinApplication]
- // and [tree.ClassNode].
- tree.NodeList makeInterfaces(Link<types.DartType> interfaces,
- Set<types.DartType> mixinTypes,
- {bool forNamedMixinApplication: false}) {
- Link<tree.Node> typeAnnotations = const Link<tree.Node>();
- for (Link<types.DartType> link = interfaces;
- !link.isEmpty;
- link = link.tail) {
- types.DartType interface = link.head;
- if (!mixinTypes.contains(interface)) {
- typeAnnotations =
- typeAnnotations.prepend(makeType(createTypeAnnotation(interface)));
- }
- }
- if (typeAnnotations.isEmpty) {
- return forNamedMixinApplication ? null : new tree.NodeList.empty();
- } else {
- return new tree.NodeList(
- forNamedMixinApplication ? null : implementsToken,
- typeAnnotations, null, ',');
- }
- }
-
- /// Creates a [tree.NamedMixinApplication] node for [cls].
- // TODO(johnniwinther): Unify creation of mixin lists between
- // [NamedMixinApplicationElement] and [ClassElement].
- tree.NamedMixinApplication makeNamedMixinApplication(
- elements.MixinApplicationElement cls) {
-
- assert(dart2js.invariant(cls, !cls.isUnnamedMixinApplication,
- message: "Cannot create ClassNode for unnamed mixin application "
- "$cls."));
- tree.Modifiers modifiers = makeModifiers(isAbstract: cls.isAbstract);
- tree.Identifier name = makeIdentifier(cls.name);
- tree.NodeList typeParameters = makeTypeParameters(cls.typeVariables);
-
- Set<types.DartType> mixinTypes = new Set<types.DartType>();
- Link<tree.Node> mixins = const Link<tree.Node>();
-
- void addMixin(types.DartType mixinType) {
- mixinTypes.add(mixinType);
- mixins = mixins.prepend(makeType(createTypeAnnotation(mixinType)));
- }
-
- addMixin(cls.mixinType);
-
- tree.Node superclass;
- types.InterfaceType supertype = cls.supertype;
- while (supertype.element.isUnnamedMixinApplication) {
- elements.MixinApplicationElement mixinApplication = supertype.element;
- addMixin(cls.asInstanceOf(mixinApplication.mixin));
- supertype = mixinApplication.supertype;
- }
- superclass =
- makeType(createTypeAnnotation(cls.asInstanceOf(supertype.element)));
- tree.Node supernode = new tree.MixinApplication(
- superclass, new tree.NodeList(null, mixins, null, ','));
-
- tree.NodeList interfaces = makeInterfaces(
- cls.interfaces, mixinTypes, forNamedMixinApplication: true);
-
- return new tree.NamedMixinApplication(
- name, typeParameters, modifiers, supernode,
- interfaces, classToken, semicolon);
- }
-
- /// Creates a [tree.ClassNode] node for [cls].
- tree.ClassNode makeClassNode(elements.ClassElement cls) {
- assert(dart2js.invariant(cls, !cls.isUnnamedMixinApplication,
- message: "Cannot create ClassNode for unnamed mixin application "
- "$cls."));
- tree.Modifiers modifiers = makeModifiers(isAbstract: cls.isAbstract);
- tree.Identifier name = makeIdentifier(cls.name);
- tree.NodeList typeParameters = makeTypeParameters(cls.typeVariables);
- tree.Node supernode;
- types.InterfaceType supertype = cls.supertype;
- Set<types.DartType> mixinTypes = new Set<types.DartType>();
- Link<tree.Node> mixins = const Link<tree.Node>();
-
- void addMixin(types.DartType mixinType) {
- mixinTypes.add(mixinType);
- mixins = mixins.prepend(makeType(createTypeAnnotation(mixinType)));
- }
-
- if (supertype != null) {
- tree.Node superclass;
- if (supertype.element.isUnnamedMixinApplication) {
- while (supertype.element.isUnnamedMixinApplication) {
- elements.MixinApplicationElement mixinApplication = supertype.element;
- addMixin(cls.asInstanceOf(mixinApplication.mixin));
- supertype = mixinApplication.supertype;
- }
- tree.Node superclass =
- makeType(createTypeAnnotation(cls.asInstanceOf(supertype.element)));
- supernode = new tree.MixinApplication(
- superclass, new tree.NodeList(null, mixins, null, ','));
- } else if (!supertype.isObject) {
- supernode = makeType(createTypeAnnotation(supertype));
- }
- }
- tree.NodeList interfaces = makeInterfaces(
- cls.interfaces, mixinTypes);
-
- Token extendsKeyword = supernode != null ? extendsToken : null;
- return new tree.ClassNode(
- modifiers, name, typeParameters, supernode,
- interfaces, openBrace, extendsKeyword,
- null, // No body.
- closeBrace);
- }
-
- tree.Node functionName(FunctionExpression exp) {
- String name = exp.name;
- if (name == null) return null;
- if (isUserDefinableOperator(name)) {
- return makeOperator("operator$name");
- } else if (name == "unary-") {
- return makeOperator("operator-");
- }
- return makeIdentifier(name);
- }
-
- tree.Node parenthesize(tree.Node node) {
- return new tree.ParenthesizedExpression(node, openParen);
- }
-
- tree.Node unparseStringLiteral(Expression exp) {
- StringLiteralOutput output = Unparser.analyzeStringLiteral(exp);
- List parts = output.parts;
- tree.Node printStringChunk(StringChunk chunk) {
- bool raw = chunk.quoting.raw;
- int quoteCode = chunk.quoting.quote;
-
- List<tree.StringInterpolationPart> literalParts = [];
- tree.LiteralString firstLiteral;
- tree.Node currentInterpolation;
-
- // sb contains the current unfinished LiteralString
- StringBuffer sb = new StringBuffer();
- if (raw) {
- sb.write('r');
- }
- for (int i = 0; i < chunk.quoting.leftQuoteCharCount; i++) {
- sb.write(chunk.quoting.quoteChar);
- }
-
- // Print every character and string interpolation
- int startIndex = chunk.previous != null ? chunk.previous.endIndex : 0;
- for (int i = startIndex; i < chunk.endIndex; i++) {
- var part = parts[i];
- if (part is Expression) {
- // Finish the previous string interpolation, if there is one.
- tree.LiteralString lit = makeVerbatimStringLiteral(sb.toString());
- if (currentInterpolation != null) {
- literalParts.add(new tree.StringInterpolationPart(
- currentInterpolation,
- lit));
- } else {
- firstLiteral = lit;
- }
- sb.clear();
- currentInterpolation = makeExpression(part);
- } else {
- int char = part;
- sb.write(Unparser.getEscapedCharacter(char, quoteCode, raw));
- }
- }
-
- // Print ending quotes
- for (int i = 0; i < chunk.quoting.rightQuoteLength; i++) {
- sb.write(chunk.quoting.quoteChar);
- }
-
- // Finish the previous string interpolation, if there is one.
- // Then wrap everything in a StringInterpolation, if relevant.
- tree.LiteralString lit = makeVerbatimStringLiteral(sb.toString());
- tree.Node node;
- if (firstLiteral == null) {
- node = lit;
- } else {
- literalParts.add(new tree.StringInterpolationPart(
- currentInterpolation,
- lit));
- node = new tree.StringInterpolation(
- firstLiteral,
- makeList('', literalParts));
- }
-
- // Juxtapose with the previous string chunks, if any.
- if (chunk.previous != null) {
- return new tree.StringJuxtaposition(
- printStringChunk(chunk.previous),
- node);
- } else {
- return node;
- }
- }
- return printStringChunk(output.chunk);
- }
-
-}

Powered by Google App Engine
This is Rietveld 408576698