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

Unified Diff: compiler/java/com/google/dart/compiler/backend/js/Normalizer.java

Issue 9479013: Remove backends. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: More clean up Created 8 years, 10 months 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: compiler/java/com/google/dart/compiler/backend/js/Normalizer.java
diff --git a/compiler/java/com/google/dart/compiler/backend/js/Normalizer.java b/compiler/java/com/google/dart/compiler/backend/js/Normalizer.java
deleted file mode 100644
index 5813042645d61fcc3be4302184d5b1b213a7c45c..0000000000000000000000000000000000000000
--- a/compiler/java/com/google/dart/compiler/backend/js/Normalizer.java
+++ /dev/null
@@ -1,1034 +0,0 @@
-// Copyright (c) 2012, 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.
-
-package com.google.dart.compiler.backend.js;
-
-import com.google.common.collect.Lists;
-import com.google.dart.compiler.InternalCompilerException;
-import com.google.dart.compiler.ast.DartArrayAccess;
-import com.google.dart.compiler.ast.DartBinaryExpression;
-import com.google.dart.compiler.ast.DartBlock;
-import com.google.dart.compiler.ast.DartCase;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartClassMember;
-import com.google.dart.compiler.ast.DartContext;
-import com.google.dart.compiler.ast.DartDefault;
-import com.google.dart.compiler.ast.DartDoWhileStatement;
-import com.google.dart.compiler.ast.DartExprStmt;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartForInStatement;
-import com.google.dart.compiler.ast.DartForStatement;
-import com.google.dart.compiler.ast.DartFunction;
-import com.google.dart.compiler.ast.DartFunctionExpression;
-import com.google.dart.compiler.ast.DartFunctionObjectInvocation;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartIfStatement;
-import com.google.dart.compiler.ast.DartInitializer;
-import com.google.dart.compiler.ast.DartIntegerLiteral;
-import com.google.dart.compiler.ast.DartLabel;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartMethodInvocation;
-import com.google.dart.compiler.ast.DartModVisitor;
-import com.google.dart.compiler.ast.DartNewExpression;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartNodeTraverser;
-import com.google.dart.compiler.ast.DartParameter;
-import com.google.dart.compiler.ast.DartParenthesizedExpression;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartRedirectConstructorInvocation;
-import com.google.dart.compiler.ast.DartReturnStatement;
-import com.google.dart.compiler.ast.DartStatement;
-import com.google.dart.compiler.ast.DartSuperConstructorInvocation;
-import com.google.dart.compiler.ast.DartSwitchMember;
-import com.google.dart.compiler.ast.DartSwitchStatement;
-import com.google.dart.compiler.ast.DartThrowStatement;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartUnaryExpression;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.DartVariable;
-import com.google.dart.compiler.ast.DartVariableStatement;
-import com.google.dart.compiler.ast.DartWhileStatement;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.parser.Token;
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.ConstructorElement;
-import com.google.dart.compiler.resolver.CoreTypeProvider;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.ElementKind;
-import com.google.dart.compiler.resolver.Elements;
-import com.google.dart.compiler.resolver.EnclosingElement;
-import com.google.dart.compiler.resolver.FieldElement;
-import com.google.dart.compiler.resolver.LabelElement;
-import com.google.dart.compiler.resolver.MethodElement;
-import com.google.dart.compiler.resolver.SyntheticDefaultConstructorElement;
-import com.google.dart.compiler.resolver.VariableElement;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Types;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Normalization phase of Dart compiler. Rewrites the AST to simplify later
- * phases.
- * <ul>
- * <li>Split 'type' declarations such as "int a = 0, b = 0"
- * <li>Introduce block statements for control structures such as IF, WHILE, and
- * FOR
- * <li>normalize case statements, including adding FallThroughError throws
- * <li>pull initializers out of FOR loops
- * <li>remove useless statement labels
- * <li>remove parenthesized expression nodes
- * </ul>
- */
-public class Normalizer {
-
- public DartUnit exec(DartUnit unit, CoreTypeProvider typeProvider) {
- new ParenNormalizer().accept(unit);
- new BlockNormalizer(typeProvider).accept(unit);
- new ForLoopInitNormalizer().accept(unit);
- // Now that the have been inserted and the For VAR has been
- // pulled out. It is easy to split up the VAR declarations.
- new VarNormalizer().accept(unit);
- unit.accept(new NormalizerVisitor());
- // debugPrint(unit);
- return unit;
- }
-
- @SuppressWarnings("unused")
- private void debugPrint(DartUnit unit) {
- DartNodeTraverser<Void> debugPrinter = new DartNodeTraverser<Void>() {
- @Override
- public Void visitClassMember(DartClassMember<?> node) {
- System.err.println(node);
- return super.visitClassMember(node);
- }
-
- @Override
- public Void visitNode(DartNode node) {
- DartNode normalizedNode = node.getNormalizedNode();
- if (node != normalizedNode) {
- System.err.println("orig: " + node);
- System.err.println("norm: " + normalizedNode);
- System.err.println();
- }
- return super.visitNode(node);
- }
- };
- unit.accept(debugPrinter);
- }
-
- /**
- * Minimize the complexity of adding statements to the AST by inserting BLOCK
- * nodes where there can be statements, after this pass there are only
- * three statement holders: BLOCK, FOR, and LABEL.
- * <p>
- * This also simplifies scope handling.
- * <p>
- * The complexity of dealing with LABEL statements is reduced by minimizing
- * the number of places that a label can be used to four statement types:
- * BLOCK, FOR, WHILE, and DO-WHILE.
- * BLOCK could also be removed by using "label:do { statement } while (false);"
- * should we choose to.
- */
- private static class BlockNormalizer extends DartModVisitor {
-
- private final ConstructorElement fallThroughError;
-
- private static ConstructorElement getFallThroughError(
- CoreTypeProvider typeProvider) {
- ClassElement element = typeProvider.getFallThroughError().getElement();
- // TODO(fabiomfv): remove local resolution once we settle on the approach.
- ConstructorElement constructor = element.lookupConstructor("");
- if (constructor == null) {
- throw new InternalCompilerException("FallThroughError does not have unnamed constructor.");
- }
- return constructor;
- }
-
- public BlockNormalizer(CoreTypeProvider typeProvider) {
- fallThroughError = getFallThroughError(typeProvider);
- }
-
- @Override
- public void endVisit(DartLabel x, DartContext ctx) {
- DartStatement body = x.getStatement();
- if (body instanceof DartVariableStatement) {
- // TODO(johnlenz): I'm assuming labelled statements don't introduce
- // a new scope.
- // Don't push a single VAR into a BLOCK, the label can't be referenced
- // so drop it entirely.
- ctx.replaceMe(body);
- } else if (!(body instanceof DartBlock) && !canContinueControlStructure(body)) {
- DartIdentifier label = x.getLabel();
- DartLabel replacement = new DartLabel(label, maybeAddBlock(body));
- LabelElement element = (LabelElement) x.getSymbol();
- element.setNode(replacement);
- replacement.setSymbol(element);
- replacement.setSourceInfo(x);
- ctx.replaceMe(replacement);
- }
- }
-
- /**
- * @return Whether this is a control structure that can be used
- * with a named "continue" statement.
- */
- private boolean canContinueControlStructure(DartStatement stmt) {
- if (stmt instanceof DartForStatement
- || stmt instanceof DartWhileStatement
- || stmt instanceof DartDoWhileStatement) {
- return true;
- }
- return false;
- }
-
- @Override
- public void endVisit(DartForStatement x, DartContext ctx) {
- DartStatement body = x.getBody();
- if (!(body instanceof DartBlock)) {
- DartStatement init = x.getInit();
- DartExpression condition = x.getCondition();
- DartExpression increment = x.getIncrement();
-
- DartStatement replacement = new DartForStatement(
- init, condition, increment, maybeAddBlock(body));
- replacement.setSourceInfo(x);
- ctx.replaceMe(replacement);
- }
- }
-
- @Override
- public void endVisit(DartIfStatement x, DartContext ctx) {
- DartStatement thenStmt = x.getThenStatement();
- DartStatement elseStmt = x.getElseStatement();
- if (!(thenStmt instanceof DartBlock) || !(elseStmt instanceof DartBlock)) {
- DartExpression condition = x.getCondition();
-
- // TODO(johnlenz): Preserve source location?
- DartIfStatement replacement = new DartIfStatement(
- condition,
- maybeAddBlock(thenStmt),
- (elseStmt != null) ? maybeAddBlock(elseStmt) : null);
- replacement.setSourceInfo(x);
- ctx.replaceMe(replacement);
- }
- }
-
- @Override
- public void endVisit(DartWhileStatement x, DartContext ctx) {
- DartStatement body = x.getBody();
- if (!(body instanceof DartBlock)) {
- DartExpression condition = x.getCondition();
-
- // TODO(johnlenz): Preserve source location?
- DartWhileStatement replacement = new DartWhileStatement(
- condition, maybeAddBlock(body));
- replacement.setSourceInfo(x);
- ctx.replaceMe(replacement);
- }
- }
-
- @Override
- public void endVisit(DartDoWhileStatement x, DartContext ctx) {
- DartStatement body = x.getBody();
- if (!(body instanceof DartBlock)) {
- DartExpression condition = x.getCondition();
-
- // TODO(johnlenz): Preserve source location?
- DartDoWhileStatement replacement = new DartDoWhileStatement(
- condition, maybeAddBlock(body));
- replacement.setSourceInfo(x);
- ctx.replaceMe(replacement);
- }
- }
-
- /**
- * Normalize case statements. There are two main things to be accomplished:
- * <ol>
- * <li>add throw new FallThroughError at the end of non-empty cases which
- * may fall through to the next block
- * <li>wrap individual statements or empty cases in blocks
- * </ol>
- *
- * For example:
- * <pre>
- * case 1:
- * case 2: ...
- * </pre>
- * becomes
- * <pre>
- * case 1: {}
- * case 2: ...
- * </pre>
- * while this:
- * <pre>
- * case 1: {}
- * case 2: ...
- * </pre>
- * becomes
- * <pre>
- * case 1: { throw new FallThroughError(); }
- * case 2: ...
- * </pre>
- * The last case (and any empty labels that fall through into it) does not get
- * a throw added, but does get changed to an empty block.
- *
- * @param caseStmt the "case: stmt;*" block being normalized
- * @param ctx {@link DartContext}
- */
- @Override
- public void endVisit(DartCase caseStmt, DartContext ctx) {
- List<DartStatement> stmts = caseStmt.getStatements();
- if (stmts.size() == 0) {
- replaceWithBlock(stmts, Lists.newArrayList(stmts));
- return;
- }
-
- // unpack an outer block if present
- List<DartStatement> innerStatements = stmts;
- if (stmts.get(0) instanceof DartBlock) {
- innerStatements = ((DartBlock) stmts.get(0)).getStatements();
- }
-
- // check if we need to add a throw
- boolean needsThrow = !isLastSwitchMember(caseStmt);
- if (needsThrow) {
- // TODO(jat): should we only look at the last statement?
- // DartParser.parseCaseStatemets seems to stop as soon as it hits an
- // AbruptCompletingStatement.
- for (DartStatement stmt : innerStatements) {
- if (stmt.isAbruptCompletingStatement()) {
- needsThrow = false;
- break;
- }
- }
- }
-
- // if we don't need to modify the block, nothing to do
- if (!needsThrow && stmts.get(0) instanceof DartBlock) {
- return;
- }
-
- // copy the list of statements and add a throw
- List<DartStatement> newStmts = Lists.newArrayList(innerStatements);
- if (needsThrow) {
- newStmts.add(buildThrow(fallThroughError));
- }
- caseStmt.setNormalizedNode(new DartCase(caseStmt.getExpr(), caseStmt.getLabel(), newStmts));
- replaceWithBlock(stmts, newStmts);
- }
-
- /**
- * Check to see if the supplied switch member is the last one in the switch
- * statement, or is allowed to fall through to the last one.
- *
- * @param member
- * @return true if the specified member is the last one in the switch
- * statement or is allowed to fall through to the l
- */
- private boolean isLastSwitchMember(DartSwitchMember member) {
- /*
- * We are replacing empty switch members with empty blocks as we go, but
- * that is ok because we start from the end here.
- */
- DartSwitchStatement switchStmt = (DartSwitchStatement) member.getParent();
- List<DartSwitchMember> members = switchStmt.getMembers();
- int i = members.size() - 1;
- if (members.get(i) == member) {
- // last switch member
- return true;
- }
- // now we only want ones that are empty and have no non-empty switch members
- // between them and the last member
- while (i >= 0) {
- DartSwitchMember curMember = members.get(i);
- if (curMember.getStatements().size() > 0) {
- // non-empty, so no earlier members can fall through
- return false;
- }
- if (curMember == member) {
- return true;
- }
- i--;
- }
- return false;
- }
-
- /**
- * Create a throw new ExceptionCtor() statement.
- *
- * @param exceptionCtor constructor to use to create exception instance
- * @param args zero or more arguments for the supplied constructor
- * @return a {@link DartStatement} representing a throw of the supplied
- * exception
- */
- private static DartStatement buildThrow(ConstructorElement exceptionCtor,
- DartExpression... args) {
- // Create AST nodes representing 'throw new FallThroughException();'.
- DartNewExpression newExpr = new DartNewExpression(new DartTypeNode(new DartIdentifier(
- exceptionCtor.getName())), Arrays.asList(args), false);
- newExpr.setSymbol(exceptionCtor);
- return new DartThrowStatement(newExpr);
- }
-
- /**
- * @param stmts
- * @param newStmts
- */
- private void replaceWithBlock(List<DartStatement> stmts, List<DartStatement> newStmts) {
- DartBlock block = new DartBlock(newStmts);
- stmts.clear();
- stmts.add(block);
- }
-
- @Override
- public void endVisit(DartDefault member, DartContext ctx) {
- // default labels must be last, so they do not need to throw FallThroughErrors
- // So, all we need to do is make sure they are blocks
- List<DartStatement> stmts = member.getStatements();
- if (stmts.size() == 0 || !(stmts.get(0) instanceof DartBlock)) {
- replaceWithBlock(stmts, Lists.newArrayList(stmts));
- }
- }
-
- private DartBlock maybeAddBlock(DartStatement statement) {
- if (statement instanceof DartBlock) {
- return (DartBlock)statement;
- }
- return new DartBlock(Lists.newArrayList(statement));
- }
- }
-
- /**
- * Extract the any initializer statements out of the FOR loop. This is done
- * to minimize the amount of code that needs to be special cased for handling
- * expressions in a FOR loop.
- */
- private static class ForLoopInitNormalizer extends DartModVisitor {
- @Override
- public boolean visit(DartLabel x, DartContext ctx) {
- // Pulled any FOR loop initializer expressions up above the label,
- // we do this in the visit to allow the DartForStatement to handle
- // the unlabelled case.
-
- LabeledForVisitor labelVisitor = new LabeledForVisitor();
- labelVisitor.accept(x);
- if (labelVisitor.forInit != null) {
- // FOR loop initializer need to be scoped, put them in a block.
- List<DartStatement> stmts = Lists.newArrayList(labelVisitor.forInit, x);
- DartBlock replacement = new DartBlock(stmts);
- ctx.replaceMe(replacement);
-
- // The removed expression hasn't be visited yet, do it now so it isn't
- // skipped.
- accept(replacement);
- }
- return true;
- }
-
- @Override
- public void endVisit(DartForStatement x, DartContext ctx) {
- DartStatement init = x.getInit();
- if (init != null) {
- DartStatement body = x.getBody();
- DartExpression condition = x.getCondition();
- DartExpression increment = x.getIncrement();
-
- DartStatement newFor = new DartForStatement(
- null, condition, increment, body);
- newFor.setSourceInfo(x);
-
- // FOR loop initializer need to be scoped, put them in a block.
- DartStatement replacementBlock = new DartBlock(
- Lists.newArrayList(init, newFor));
-
- ctx.replaceMe(replacementBlock);
- }
- }
-
- private static class LabeledForVisitor extends DartModVisitor {
- DartStatement forInit = null;
-
- @Override
- public boolean visit(DartForStatement x, DartContext ctx) {
- if (x.getInit() != null) {
- DartStatement init = x.getInit();
- if (init != null) {
- DartStatement body = x.getBody();
- DartExpression condition = x.getCondition();
- DartExpression increment = x.getIncrement();
-
- // TODO(johnlenz): Preserve source location?
- DartStatement newFor = new DartForStatement(
- null, condition, increment, body);
- newFor.setSourceInfo(x);
- ctx.replaceMe(newFor);
- }
- forInit = init;
- }
- return false;
- }
-
- @Override
- public boolean visit(DartLabel x, DartContext ctx) {
- DartStatement stmt = x.getStatement();
- return (stmt instanceof DartLabel) || (stmt instanceof DartForStatement);
- }
- }
- }
-
- /**
- * Remove parenthesized expression nodes. This simplifies all of the rest of
- * the normalizers by not requiring them to deal with this special case.
- */
- private static class ParenNormalizer extends DartModVisitor {
- @Override
- public void endVisit(DartParenthesizedExpression x, DartContext ctx) {
- ctx.replaceMe(x.getExpression());
- }
- }
-
- /**
- * Split VAR declarations so that there is only one VAR declaration per
- * statement. This simplifies rewriting of VAR statements.
- */
- private static class VarNormalizer extends DartModVisitor {
- @Override
- public void endVisit(DartVariableStatement x, DartContext ctx) {
- List<DartVariable> vars = x.getVariables();
- if (vars.size() > 1) {
- for (DartVariable v : vars) {
- DartVariableStatement stmt = new DartVariableStatement(
- Lists.newArrayList(v), x.getTypeNode());
- stmt.setSourceInfo(v);
- ctx.insertBefore(stmt);
- }
- ctx.removeMe();
- }
- }
- }
-
- /**
- * The actual normalization.
- */
- private static class NormalizerVisitor extends DartNodeTraverser<DartNode> {
- // Collects names to avoid conflicts with synthesized variables.
- private final Set<String> usedNames = new HashSet<String>();
-
- @Override
- public DartNode visitClassMember(DartClassMember<?> node) {
- usedNames.clear();
- return super.visitClassMember(node);
- }
-
- @Override
- public DartNode visitForInStatement(DartForInStatement node) {
- node.visitChildren(this);
-
- // Normalize for (var? name in expression) { ... } into:
- // {
- // var i = expression.iterator();
- // while (i.hasNext()) {
- // var? name = i.next();
- // ...
- // }
- // }
- List<DartStatement> topLevelStatements = new ArrayList<DartStatement>();
-
- // Generate the call to expression.iterator().
- DartMethodInvocation iteratorCall = call(node.getIterable(), "iterator");
-
- // Create and add the iterator variable to the statements.
- DartVariableStatement iteratorVariable = makeTempVariable(0, iteratorCall);
- topLevelStatements.add(iteratorVariable);
-
- // Generate the call to i.hasNext();
- DartIdentifier iterator = ref(iteratorVariable);
- DartMethodInvocation hasNext = call(iterator, "hasNext");
-
- // Generate the call to i.next();
- iterator = ref(iteratorVariable);
- DartMethodInvocation next = call(iterator, "next");
-
- DartStatement setup = normalizeForInSetup(node, next);
- DartWhileStatement whileStatement = whileStmt(hasNext, setup, node.getBody());
- topLevelStatements.add(whileStatement);
-
- DartBlock newBlock = new DartBlock(topLevelStatements);
- node.setNormalizedNode(newBlock);
- return node;
- }
-
- private DartStatement normalizeForInSetup(DartForInStatement node, DartExpression next) {
- if (node.introducesVariable()) {
- // Since we're going to change the variable to have an initializer expression,
- // we have to create a new variable statement around it too. Make sure it has
- // the right type and modifiers.
- DartVariableStatement variableStatement = node.getVariableStatement();
- DartVariable oldVariable = variableStatement.getVariables().get(0);
- DartVariable newVariable = new DartVariable(oldVariable.getName(), next);
- newVariable.setSymbol(oldVariable.getSymbol());
- return new DartVariableStatement(Lists.newArrayList(newVariable),
- variableStatement.getTypeNode(), variableStatement.getModifiers());
- } else {
- return exprStmt(assign(node.getIdentifier(), next));
- }
- }
-
- @Override
- public DartNode visitClass(DartClass node) {
- final ClassElement classElement = node.getSymbol();
- // Ensure implicit default constructor with method.
- if (Elements.needsImplicitDefaultConstructor(classElement)) {
- DartMethodDefinition method = createImplicitDefaultConstructor(classElement);
- // TODO - We should really normalize the class itself.
- node.getMembers().add(method);
- }
- return super.visitClass(node);
- }
-
- private DartMethodDefinition createImplicitDefaultConstructor(final ClassElement classElement) {
- assert (Elements.needsImplicitDefaultConstructor(classElement));
- DartFunction function = new DartFunction(Collections.<DartParameter>emptyList(),
- new DartBlock(Collections.<DartStatement>emptyList()), null);
- final DartMethodDefinition method =
- DartMethodDefinition.create(new DartIdentifier(""), function, Modifiers.NONE, null);
- method.setSymbol(new SyntheticDefaultConstructorElement(method, classElement, null));
- return method;
- }
-
- @Override
- public DartExpression visitBinaryExpression(DartBinaryExpression node) {
- node.visitChildren(this);
- Token operator = node.getOperator();
- if (operator.isAssignmentOperator() && operator != Token.ASSIGN) {
- node.setNormalizedNode(normalizeCompoundAssignment(mapAssignableOp(operator), false,
- node.getArg1().getNormalizedNode(),
- node.getArg2().getNormalizedNode()));
- }
- return node;
- }
-
- @Override
- public DartExpression visitUnaryExpression(DartUnaryExpression node) {
- node.visitChildren(this);
- Token operator = node.getOperator();
- if (operator.isCountOperator()) {
- DartExpression lhs = node.getArg().getNormalizedNode();
- DartIntegerLiteral rhs = DartIntegerLiteral.one();
- node.setNormalizedNode(normalizeCompoundAssignment(mapAssignableOp(operator),
- !node.isPrefix(), lhs, rhs));
- }
- return node;
- }
-
- static class NeedsImplicitSuperInvocationDeterminant extends DartNodeTraverser<Void> {
- private boolean needsSuperInvocation = true;
-
- @Override
- public Void visitSuperConstructorInvocation(DartSuperConstructorInvocation node) {
- needsSuperInvocation = false;
- return super.visitSuperConstructorInvocation(node);
- }
-
- @Override
- public Void visitRedirectConstructorInvocation(DartRedirectConstructorInvocation node) {
- needsSuperInvocation = false;
- return super.visitRedirectConstructorInvocation(node);
- }
-
- @Override
- public Void visitMethodDefinition(DartMethodDefinition node) {
- // Ignore everything except the initializers
- for (DartInitializer initializer : node.getInitializers()) {
- initializer.accept(this);
- }
- return null;
- }
- }
-
- @Override
- public DartMethodDefinition visitMethodDefinition(DartMethodDefinition node) {
- super.visitMethodDefinition(node);
- if (Elements.isNonFactoryConstructor(node.getSymbol())) {
- normalizeParameterInitializer(node);
- }
-
- return node;
- }
-
- @Override
- public DartNode visitNewExpression(DartNewExpression node) {
- ConstructorElement symbol = node.getSymbol();
- if (symbol == null) {
- InterfaceType constructorType = Types.constructorType(node);
- if (!constructorType.getElement().isDynamic() && node.getArgs().isEmpty()) {
- // HACK use proper normalized node
- ClassElement classToInstantiate = constructorType.getElement();
- if (classToInstantiate.getDefaultClass() != null) {
- classToInstantiate = classToInstantiate.getDefaultClass().getElement();
- }
-
- if (classToInstantiate != null
- && Elements.needsImplicitDefaultConstructor(classToInstantiate)) {
- DartMethodDefinition implicitDefaultConstructor =
- createImplicitDefaultConstructor(classToInstantiate);
- node.setSymbol(implicitDefaultConstructor.getSymbol());
- }
- }
- }
-
- return super.visitNewExpression(node);
- }
-
- @Override
- public DartNode visitSwitchStatement(DartSwitchStatement node) {
- node.getExpression().accept(this);
- for (DartNode member : node.getMembers()) {
- member.accept(this);
- }
- return node;
- }
-
- // Normalize parameter initializer.
- // transforms: class A { A(this.x) { } }
- // into: class A { A(this.x) : this.x = x { }
- private void normalizeParameterInitializer(DartMethodDefinition node) {
- List<DartInitializer> nInit = new ArrayList<DartInitializer>();
- for (DartParameter param : node.getFunction().getParams()) {
- FieldElement fieldElement = param.getSymbol().getParameterInitializerElement();
- if (fieldElement != null) {
- DartIdentifier left = new DartIdentifier(param.getParameterName());
- left.setSymbol(fieldElement);
- left.setSourceInfo(param);
- Element ve = Elements.makeVariable(param.getParameterName());
- DartParameter nParam = new DartParameter(param.getName(), param.getTypeNode(),
- param.getFunctionParameters(), param.getDefaultExpr(), param.getModifiers());
- nParam.setSymbol(ve);
- param.setNormalizedNode(nParam);
- DartIdentifier right = new DartIdentifier(param.getParameterName());
- right.setSymbol(ve);
- right.setSourceInfo(param);
- DartInitializer di = new DartInitializer(left, right);
- di.setSourceInfo(param);
- nInit.add(di);
- }
- }
-
- EnclosingElement enclosingElement = node.getSymbol().getEnclosingElement();
- if (ElementKind.of(enclosingElement) == ElementKind.CLASS) {
- ClassElement classElement = (ClassElement) enclosingElement;
- if (!classElement.isObject()) {
- NeedsImplicitSuperInvocationDeterminant superLocator = new NeedsImplicitSuperInvocationDeterminant();
- node.accept(superLocator);
- if (superLocator.needsSuperInvocation) {
- DartSuperConstructorInvocation superInvocation = new DartSuperConstructorInvocation(
- new DartIdentifier(""), Collections.<DartExpression>emptyList());
- // Set constructor element - actual constructor with all named parameters or synthetic.
- ConstructorElement superConstructorElement = null;
- {
- ClassElement superTypeElement = classElement.getSupertype().getElement();
- List<ConstructorElement> constructors = superTypeElement.getConstructors();
- for (ConstructorElement constructor : constructors) {
- if (hasOnlyNamedParameters(constructor)) {
- superConstructorElement = constructor;
- break;
- }
- }
- if (superConstructorElement == null) {
- superConstructorElement =
- new SyntheticDefaultConstructorElement(null, superTypeElement, null);
- }
- superInvocation.setSymbol(superConstructorElement);
- }
- // Add implicit "super" invocation.
- nInit.add(new DartInitializer(null, superInvocation));
- }
- }
- }
-
- if (!nInit.isEmpty()) {
- if (!node.getInitializers().isEmpty()) {
- nInit.addAll(0, node.getInitializers());
- }
-
- DartMethodDefinition nConstructor = DartMethodDefinition.create(
- node.getName(), node.getFunction(), node.getModifiers(), nInit);
- nConstructor.setSymbol(node.getSymbol());
- nConstructor.setSourceInfo(node.getSourceInfo());
- node.setNormalizedNode(nConstructor);
- }
- }
-
- /**
- * @return <code>true</code> if given constructor has only named (i.e. optional) parameters.
- */
- private static boolean hasOnlyNamedParameters(ConstructorElement constructor) {
- for (VariableElement parameter : constructor.getParameters()) {
- if (!parameter.isNamed()) {
- return false;
- }
- }
- return true;
- }
-
- private DartExpression normalizeCompoundAssignment(Token operator,
- boolean isPostfix,
- DartExpression operand1,
- DartExpression operand2) {
- return operand1.accept(new CompoundAssignmentNormalizer(operator, isPostfix, operand2));
- }
-
- private String makeTempName(int i) {
- String name;
- do {
- name = "$" + i;
- i++;
- } while (usedNames.contains(name));
- usedNames.add(name);
- return name;
- }
-
- private DartVariableStatement makeTempVariable(int i, DartExpression init) {
- String variableName = makeTempName(i);
- DartIdentifier variableIdentifier = new DartIdentifier(variableName);
- DartVariable variable = new DartVariable(variableIdentifier, init);
- VariableElement element = Elements.variableElement(variable,
- variableName,
- Modifiers.NONE);
- variable.setSymbol(element);
- return new DartVariableStatement(Lists.newArrayList(variable), null);
- }
-
- private class Let {
- private final List<DartExpression> arguments;
- final DartParameter[] parameters;
-
- Let(DartExpression... arguments) {
- this.arguments = Arrays.asList(arguments);
- parameters = new DartParameter[arguments.length];
- for (int i = 0; i < arguments.length; i++) {
- parameters[i] = makeTempParameter(i);
- }
- }
-
- DartExpression expression() {
- DartBlock body = new DartBlock(Arrays.<DartStatement>asList(body()));
- return call(makeFunctionExpression(body), arguments);
- }
-
- private DartFunctionExpression makeFunctionExpression(DartBlock body) {
- DartFunction function = new DartFunction(Arrays.asList(parameters), body , null);
- DartFunctionExpression expression = new DartFunctionExpression(null, function, false);
- MethodElement element =
- Elements.methodFromFunctionExpression(expression, Modifiers.NONE.makeInlinable());
- expression.setSymbol(element);
- for (DartParameter parameter : parameters) {
- Elements.addParameter(element, parameter.getSymbol());
- }
- return expression;
- }
-
- DartExpression p(int i) {
- return ref(parameters[i]);
- }
-
- DartStatement[] body() {
- return new DartStatement[0];
- }
-
- private DartParameter makeTempParameter(int i) {
- String name = makeTempName(i);
- DartIdentifier identifier = new DartIdentifier(name);
- DartParameter parameter = new DartParameter(identifier, null, null, null, Modifiers.NONE);
- VariableElement element = Elements.parameterElement(parameter, name, Modifiers.NONE);
- parameter.setSymbol(element);
- return parameter;
- }
- }
-
- private class CompoundAssignmentNormalizer extends DartNodeTraverser<DartExpression> {
- final Token operator;
- final boolean isPostfix;
- final DartExpression rhs;
-
- CompoundAssignmentNormalizer(Token operator, boolean isPostfix,
- DartExpression rhs) {
- this.operator = operator;
- this.isPostfix = isPostfix;
- this.rhs = rhs;
- }
-
- @Override
- public DartExpression visitNode(DartNode lhs) {
- throw new AssertionError(lhs);
- }
-
- @Override
- public DartExpression visitIdentifier(DartIdentifier id) {
- return rewriteExpression(id);
- }
-
- private DartExpression rewriteExpression(final DartExpression lhs) {
- if (!isPostfix) {
- // Turns: lhs += rhs
- // Into: lhs = lhs + rhs
- // Turns: ++lhs
- // Into: lhs = lhs + 1
- return assign(lhs, bin(operator, lhs, rhs));
- } else {
- // Turns: lhs++
- // Into: function($2) { id = $2 + 1; return $2; }(lhs)
- return new Let(lhs) {
- @Override DartStatement[] body() {
- return statements(exprStmt(assign(lhs, bin(operator, p(0), rhs))),
- retrn(p(0)));
- }
- }.expression();
- }
- }
-
- @Override
- public DartExpression visitPropertyAccess(DartPropertyAccess access) {
- Element element = access.getTargetSymbol();
- if (element != null && element.getModifiers().isStatic()) {
- return rewriteExpression(access);
- }
- final DartIdentifier name = access.getName();
- return new RewriteAccess((DartExpression) access.getQualifier()) {
- @Override
- DartExpression operand1() {
- return access(p(0), name);
- }
- }.expression();
- }
-
- @Override
- public DartExpression visitArrayAccess(DartArrayAccess access) {
- DartExpression target = access.getTarget();
- DartExpression key = access.getKey();
- // TODO(5408710): Evaluation order of target vs. key? (order passed to constructor)
- return new RewriteAccess(target, key) {
- @Override
- DartExpression operand1() {
- return arrayAccess(p(0), p(1));
- }
- }.expression();
- }
-
- private abstract class RewriteAccess extends Let {
- public RewriteAccess(DartExpression... arguments) {
- super(arguments);
- }
-
- abstract DartExpression operand1();
-
- @Override
- DartStatement[] body() {
- final DartExpression operand1 = operand1();
- if (isPostfix) {
- // Turns: this[0.0]--
- // Into: function($0, $1) {
- // return function($2) { $0[$1] = $2 - 1; return $2; }($0[$1]);
- // }(this, 0.0)
- Let let = new Let(operand1) {
- @Override DartStatement[] body() {
- return statements(exprStmt(assign(operand1, bin(operator, p(0), rhs))),
- retrn(p(0)));
- }
- };
- return statements(retrn(let.expression()));
- } else {
- // Turns: this[0.0] += $0
- // Into: function($3, $4) { return $3[$4] = $3[$4] + $0; }(this, 0.0)
- // Turns: ++this[0.0]
- // Into: function($3, $4) { return $3[$4] = $3[$4] + 1; }(this, 0.0)
- return statements(retrn(assign(operand1, bin(operator, operand1, rhs))));
- }
- }
- }
- }
-
- private DartStatement[] statements(DartStatement... statements) {
- return statements;
- }
-
- private DartWhileStatement whileStmt(DartExpression condition, DartStatement... statements) {
- return new DartWhileStatement(condition, new DartBlock(Arrays.asList(statements)));
- }
-
- private DartExpression call(DartFunctionExpression function, List<DartExpression> args) {
- return new DartFunctionObjectInvocation(function, args);
- }
-
- private DartMethodInvocation call(DartExpression receiver, String name) {
- return new DartMethodInvocation(receiver,
- new DartIdentifier(name),
- Collections.<DartExpression>emptyList());
- }
-
- private DartArrayAccess arrayAccess(DartExpression target, DartExpression key) {
- return new DartArrayAccess(target, key);
- }
-
- private DartReturnStatement retrn(DartExpression value) {
- return new DartReturnStatement(value);
- }
-
- private DartBinaryExpression bin(Token operator, DartExpression lhs, DartExpression rhs) {
- return new DartBinaryExpression(operator, lhs, rhs);
- }
-
- private DartBinaryExpression assign(DartExpression lhs, DartExpression rhs) {
- return bin(Token.ASSIGN, lhs, rhs);
- }
-
- private DartExprStmt exprStmt(DartExpression expression) {
- return new DartExprStmt(expression);
- }
-
- private DartPropertyAccess access(DartExpression qualifier, DartIdentifier name) {
- return new DartPropertyAccess(qualifier, name);
- }
-
- private DartExpression ref(DartParameter parameter) {
- DartIdentifier identifier = new DartIdentifier(parameter.getParameterName());
- identifier.setSymbol(parameter.getSymbol());
- return identifier;
- }
-
- private DartIdentifier ref(DartVariableStatement variableStatement) {
- DartVariable variable = variableStatement.getVariables().get(0);
- DartIdentifier identifier = new DartIdentifier(variable.getVariableName());
- identifier.setSymbol(variable.getSymbol());
- return identifier;
- }
-
- private Token mapAssignableOp(Token operator) {
- switch (operator) {
- case ASSIGN_BIT_OR: return Token.BIT_OR;
- case ASSIGN_BIT_XOR: return Token.BIT_XOR;
- case ASSIGN_BIT_AND: return Token.BIT_AND;
- case ASSIGN_SHL: return Token.SHL;
- case ASSIGN_SAR: return Token.SAR;
- case ASSIGN_ADD: return Token.ADD;
- case ASSIGN_SUB: return Token.SUB;
- case ASSIGN_MUL: return Token.MUL;
- case ASSIGN_DIV: return Token.DIV;
- case ASSIGN_MOD: return Token.MOD;
- case ASSIGN_TRUNC: return Token.TRUNC;
- case INC: return Token.ADD;
- case DEC: return Token.SUB;
-
- default:
- throw new InternalCompilerException("Invalid assignment operator");
- }
- }
- }
-}

Powered by Google App Engine
This is Rietveld 408576698