Decouple JsProgram; this allows the JS AST to serialize in pieces. 1) A rethinking of how JsScope should work. Most notably, the JsRootScope is a singleton with special serialization. I also refactored bits and pieces of the JsScope hierarchy to get rid of fields and code that don't make sense for particular subclasses. And I broke serialization circular references (that pull in the whole world) by not having scopes serialize their children. 2) I got JsProgram out of the business of federating literals and singletons. This is much more like how the Java AST works now. http://gwt-code-reviews.appspot.com/1342801/show git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9683 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java b/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java index 9decb5a..3888f9d 100644 --- a/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java +++ b/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java
@@ -114,11 +114,6 @@ } @Override - public JsProgram program() { - return func.getScope().getProgram(); - } - - @Override public String toString() { return func.toString(); } @@ -251,8 +246,8 @@ int jsLine = info.getStartLine() + countLines(indexes, info.getStartPos(), absoluteJsStartPos); - SourceInfo jsInfo = SourceOrigin.create(jsStartPos, jsEndPos, jsLine, - info.getFileName()); + SourceInfo jsInfo = jsProgram.createSourceInfo(jsStartPos, jsEndPos, + jsLine, info.getFileName()); try { List<JsStatement> result = JsParser.parse(jsInfo, jsProgram.getScope(), sr);
diff --git a/dev/core/src/com/google/gwt/dev/javac/JsniMethod.java b/dev/core/src/com/google/gwt/dev/javac/JsniMethod.java index fd0c87b..616ff10 100644 --- a/dev/core/src/com/google/gwt/dev/javac/JsniMethod.java +++ b/dev/core/src/com/google/gwt/dev/javac/JsniMethod.java
@@ -16,7 +16,6 @@ package com.google.gwt.dev.javac; import com.google.gwt.dev.js.ast.JsFunction; -import com.google.gwt.dev.js.ast.JsProgram; /** * Represents a single JsniMethod in a compiled class file. @@ -53,9 +52,4 @@ * The parameter names. */ public abstract String[] paramNames(); - - /** - * Gets the JsProgram in which this method is located. - */ - public abstract JsProgram program(); }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/CorrelationFactory.java b/dev/core/src/com/google/gwt/dev/jjs/CorrelationFactory.java index be0fbfb..b280c37 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/CorrelationFactory.java +++ b/dev/core/src/com/google/gwt/dev/jjs/CorrelationFactory.java
@@ -40,6 +40,16 @@ * A dummy factory that always returns <code>null</code>. */ public static final class DummyCorrelationFactory extends CorrelationFactory { + public static final CorrelationFactory INSTANCE = new DummyCorrelationFactory(); + + private DummyCorrelationFactory() { + } + + @Override + public Correlation by(JDeclaredType type) { + return null; + } + @Override public Correlation by(JField field) { return null; @@ -51,11 +61,6 @@ } @Override - public Correlation by(JDeclaredType type) { - return null; - } - - @Override public Correlation by(JsFunction function) { return null; } @@ -99,6 +104,8 @@ * public-API consumers of the Correlation. */ + public static final CorrelationFactory INSTANCE = new RealCorrelationFactory(); + /** * Correlations based on Literals are all the same, so we'll just cook up a * Map to make {@link #by(Literal)} fast. @@ -108,8 +115,8 @@ static { for (Literal l : Literal.values()) { - LITERAL_CORRELATIONS.put(l, new Correlation(Axis.LITERAL, - l.getDescription(), l)); + LITERAL_CORRELATIONS.put(l, + new Correlation(Axis.LITERAL, l.getDescription(), l)); } } @@ -132,6 +139,19 @@ private final Map<Object, Correlation> canonicalMap = Collections.synchronizedMap(new ReferenceMap( ReferenceMap.WEAK, ReferenceMap.WEAK)); + private RealCorrelationFactory() { + } + + @Override + public Correlation by(JDeclaredType type) { + Correlation toReturn = canonicalMap.get(type); + if (toReturn == null) { + toReturn = new Correlation(Axis.CLASS, type.getName(), type); + canonicalMap.put(type, toReturn); + } + return toReturn; + } + @Override public Correlation by(JField field) { Correlation toReturn = canonicalMap.get(field); @@ -155,16 +175,6 @@ } @Override - public Correlation by(JDeclaredType type) { - Correlation toReturn = canonicalMap.get(type); - if (toReturn == null) { - toReturn = new Correlation(Axis.CLASS, type.getName(), type); - canonicalMap.put(type, toReturn); - } - return toReturn; - } - - @Override public Correlation by(JsFunction function) { Correlation toReturn = canonicalMap.get(function); if (toReturn == null) { @@ -221,12 +231,12 @@ } } + public abstract Correlation by(JDeclaredType type); + public abstract Correlation by(JField field); public abstract Correlation by(JMethod method); - public abstract Correlation by(JDeclaredType type); - public abstract Correlation by(JsFunction function); public abstract Correlation by(JsName name);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java index a50d4a1..13fce81 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java +++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -541,7 +541,7 @@ checkForErrors(logger, goldenCuds, false); CorrelationFactory correlator = options.isSoycExtra() - ? new RealCorrelationFactory() : new DummyCorrelationFactory(); + ? RealCorrelationFactory.INSTANCE : DummyCorrelationFactory.INSTANCE; JProgram jprogram = new JProgram(correlator); JsProgram jsProgram = new JsProgram(correlator);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java b/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java index a34a2b0..ccaf1c4 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java +++ b/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java
@@ -49,6 +49,11 @@ */ List<Correlation> getAllCorrelations(Axis axis); + /** + * Returns the correlation factory that created this node. + */ + CorrelationFactory getCorrelationFactory(); + int getEndPos(); String getFileName(); @@ -64,11 +69,11 @@ * has been set. */ Set<Correlation> getPrimaryCorrelations(); - + /** * Returns the first Correlations added along each Axis on which a Correlation - * has been set. Some entries may be null and should be ignored. The - * returned array must not be modified. + * has been set. Some entries may be null and should be ignored. The returned + * array must not be modified. */ Correlation[] getPrimaryCorrelationsArray(); @@ -93,6 +98,13 @@ SourceInfo makeChild(Class<?> caller, String description, SourceInfo... merge); /** + * Create a child node of the same type as this node, but with a new Origin. + * If data accumulation is enabled, the derived node will inherit its + * Correlations from this node. + */ + SourceInfo makeChild(SourceOrigin origin); + + /** * Add additional ancestor SourceInfos. These SourceInfo objects indicate that * a merge-type operation took place or that the additional ancestors have a * containment relationship with the SourceInfo.
diff --git a/dev/core/src/com/google/gwt/dev/jjs/SourceInfoCorrelation.java b/dev/core/src/com/google/gwt/dev/jjs/SourceInfoCorrelation.java index ab985f1..9176f89 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/SourceInfoCorrelation.java +++ b/dev/core/src/com/google/gwt/dev/jjs/SourceInfoCorrelation.java
@@ -16,6 +16,7 @@ package com.google.gwt.dev.jjs; import com.google.gwt.dev.jjs.Correlation.Axis; +import com.google.gwt.dev.jjs.CorrelationFactory.RealCorrelationFactory; import java.io.Serializable; import java.util.ArrayList; @@ -36,7 +37,7 @@ * Micro-opt for {@link #makeChild(Class, String)}. */ private static final SourceInfo[] EMPTY_SOURCEINFO_ARRAY = new SourceInfo[0]; - + private static final int numCorrelationAxes = Axis.values().length; private static int numCorrelationAxes() { @@ -66,18 +67,17 @@ primaryCorrelations = new Correlation[numCorrelationAxes()]; } + private SourceInfoCorrelation(SourceInfoCorrelation parent, + SourceOrigin origin) { + this.origin = origin; + this.allCorrelations = new ArrayList<Correlation>(parent.allCorrelations); + primaryCorrelations = parent.primaryCorrelations.clone(); + } + private SourceInfoCorrelation(SourceInfoCorrelation parent, String caller, SourceInfo... additionalAncestors) { - assert parent != null; + this(parent, parent.origin); assert caller != null; - this.origin = parent.origin; - - this.allCorrelations = new ArrayList<Correlation>(parent.allCorrelations); - primaryCorrelations = new Correlation[numCorrelationAxes()]; - for (int i = 0; i < numCorrelationAxes(); i++) { - primaryCorrelations[i] = parent.primaryCorrelations[i]; - } - merge(additionalAncestors); } @@ -134,6 +134,11 @@ return toReturn; } + @Override + public CorrelationFactory getCorrelationFactory() { + return RealCorrelationFactory.INSTANCE; + } + public int getEndPos() { return getOrigin().getEndPos(); } @@ -167,7 +172,7 @@ } return toReturn; } - + public Correlation[] getPrimaryCorrelationsArray() { return primaryCorrelations; } @@ -202,6 +207,11 @@ return new SourceInfoCorrelation(this, callerName, merge); } + @Override + public SourceInfo makeChild(SourceOrigin origin) { + return new SourceInfoCorrelation(this, origin); + } + /** * Add additional ancestor SourceInfos. These SourceInfo objects indicate that * a merge-type operation took place or that the additional ancestors have a
diff --git a/dev/core/src/com/google/gwt/dev/jjs/SourceOrigin.java b/dev/core/src/com/google/gwt/dev/jjs/SourceOrigin.java index 5e666d7..555c503 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/SourceOrigin.java +++ b/dev/core/src/com/google/gwt/dev/jjs/SourceOrigin.java
@@ -16,6 +16,7 @@ package com.google.gwt.dev.jjs; import com.google.gwt.dev.jjs.Correlation.Axis; +import com.google.gwt.dev.jjs.CorrelationFactory.DummyCorrelationFactory; import com.google.gwt.dev.util.StringInterner; import java.util.Collections; @@ -56,7 +57,7 @@ public int getStartPos() { return startPos; } - + // super.equals and hashCode call getStartPos() and getEndPos(), // so there is no need to implement them in this subclass } @@ -148,6 +149,11 @@ return Collections.emptyList(); } + @Override + public CorrelationFactory getCorrelationFactory() { + return DummyCorrelationFactory.INSTANCE; + } + public int getEndPos() { return -1; } @@ -167,7 +173,7 @@ public Set<Correlation> getPrimaryCorrelations() { return Collections.emptySet(); } - + public Correlation[] getPrimaryCorrelationsArray() { return new Correlation[0]; } @@ -195,6 +201,11 @@ return this; } + @Override + public SourceInfo makeChild(SourceOrigin origin) { + return origin; + } + public void merge(SourceInfo... sourceInfos) { }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java index a4ca996..020c6d6 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java +++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
@@ -15,11 +15,12 @@ */ package com.google.gwt.dev.jjs.ast; +import com.google.gwt.dev.jjs.Correlation.Literal; import com.google.gwt.dev.jjs.CorrelationFactory; +import com.google.gwt.dev.jjs.CorrelationFactory.DummyCorrelationFactory; import com.google.gwt.dev.jjs.InternalCompilerException; import com.google.gwt.dev.jjs.SourceInfo; import com.google.gwt.dev.jjs.SourceOrigin; -import com.google.gwt.dev.jjs.Correlation.Literal; import com.google.gwt.dev.jjs.ast.JField.Disposition; import com.google.gwt.dev.jjs.ast.js.JsniMethodBody; import com.google.gwt.dev.jjs.ast.js.JsonObject; @@ -107,7 +108,7 @@ private static final int IS_NULL = 0; private static final Map<String, JPrimitiveType> primitiveTypes = new HashMap<String, JPrimitiveType>(); - + @Deprecated private static final Map<String, JPrimitiveType> primitiveTypesDeprecated = new HashMap<String, JPrimitiveType>(); @@ -398,7 +399,7 @@ private JClassType typeString; public JProgram() { - this(new CorrelationFactory.DummyCorrelationFactory()); + this(DummyCorrelationFactory.INSTANCE); } /**
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java index 42bc89c..e2221ba 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java +++ b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
@@ -1,12 +1,12 @@ /* * Copyright 2008 Google Inc. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -110,7 +110,7 @@ * corresponding JNode for each created method and variable. 4) Maps all * synthetic arguments and fields for nested and local classes. 5) Slurps in * JSNI code for native methods as an opaque string. - * + * * Note that methods and fields are not added to their classes here, that * isn't done until {@link GenerateJavaAST}. */ @@ -292,13 +292,10 @@ private SourceInfo makeSourceInfo(AbstractMethodDeclaration methodDecl, HasSourceInfo enclosing) { - CompilationResult compResult = methodDecl.compilationResult; - int[] indexes = compResult.lineSeparatorPositions; - String fileName = String.valueOf(compResult.fileName); - int startLine = Util.getLineNumber(methodDecl.sourceStart, indexes, 0, - indexes.length - 1); + int startLine = Util.getLineNumber(methodDecl.sourceStart, + currentSeparatorPositions, 0, currentSeparatorPositions.length - 1); SourceInfo toReturn = program.createSourceInfo(methodDecl.sourceStart, - methodDecl.bodyEnd, startLine, fileName); + methodDecl.bodyEnd, startLine, currentFileName); // The SourceInfo will inherit Correlations from its enclosing object if (enclosing != null) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/FragmentExtractor.java b/dev/core/src/com/google/gwt/dev/jjs/impl/FragmentExtractor.java index 88c152e..502aa35 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/impl/FragmentExtractor.java +++ b/dev/core/src/com/google/gwt/dev/jjs/impl/FragmentExtractor.java
@@ -538,7 +538,7 @@ * An empty JsVars seems possibly surprising; return a true empty * statement instead. */ - return jsprogram.getEmptyStmt(); + return new JsEmpty(stat.getSourceInfo()); } }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java index 105d0f2..4c04e90 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java +++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
@@ -2995,8 +2995,7 @@ JLiteral initializer = field.getConstInitializer(); JType type = initializer.getType(); if (type instanceof JPrimitiveType || program.isJavaLangString(type)) { - GenerateJavaScriptLiterals generator = new GenerateJavaScriptLiterals( - jsProgram); + GenerateJavaScriptLiterals generator = new GenerateJavaScriptLiterals(); generator.accept(initializer); JsExpression result = generator.peek(); assert (result != null);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java index c878a3b..84de28d 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java +++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -105,6 +105,7 @@ import com.google.gwt.dev.js.ast.JsContinue; import com.google.gwt.dev.js.ast.JsDefault; import com.google.gwt.dev.js.ast.JsDoWhile; +import com.google.gwt.dev.js.ast.JsEmpty; import com.google.gwt.dev.js.ast.JsExprStmt; import com.google.gwt.dev.js.ast.JsExpression; import com.google.gwt.dev.js.ast.JsFor; @@ -118,6 +119,7 @@ import com.google.gwt.dev.js.ast.JsNameRef; import com.google.gwt.dev.js.ast.JsNew; import com.google.gwt.dev.js.ast.JsNode; +import com.google.gwt.dev.js.ast.JsNormalScope; import com.google.gwt.dev.js.ast.JsObjectLiteral; import com.google.gwt.dev.js.ast.JsParameter; import com.google.gwt.dev.js.ast.JsPostfixOperation; @@ -125,6 +127,7 @@ import com.google.gwt.dev.js.ast.JsProgram; import com.google.gwt.dev.js.ast.JsPropertyInitializer; import com.google.gwt.dev.js.ast.JsReturn; +import com.google.gwt.dev.js.ast.JsRootScope; import com.google.gwt.dev.js.ast.JsScope; import com.google.gwt.dev.js.ast.JsStatement; import com.google.gwt.dev.js.ast.JsSwitch; @@ -295,7 +298,7 @@ if (parentScope == objectScope) { parentScope = interfaceScope; } - myScope = new JsScope(parentScope, "class " + x.getShortName()); + myScope = new JsNormalScope(parentScope, "class " + x.getShortName()); } classScopes.put(x, myScope); @@ -532,10 +535,6 @@ arrayLength.setObfuscatable(false); } - public GenerateJavaScriptVisitor() { - super(jsProgram); - } - @Override public void endVisit(JAbsentArrayDimension x, Context ctx) { throw new InternalCompilerException("Should not get here."); @@ -594,7 +593,7 @@ Iterator<JsStatement> iterator = stmts.iterator(); while (iterator.hasNext()) { JsStatement stmt = iterator.next(); - if (stmt == jsProgram.getEmptyStmt()) { + if (stmt instanceof JsEmpty) { iterator.remove(); } } @@ -755,7 +754,7 @@ if (x.getBody() != null) { stmt.setBody((JsStatement) pop()); // body } else { - stmt.setBody(jsProgram.getEmptyStmt()); + stmt.setBody(new JsEmpty(x.getSourceInfo())); } stmt.setCondition((JsExpression) pop()); // testExpr push(stmt); @@ -843,7 +842,7 @@ if (x.getBody() != null) { jsFor.setBody((JsStatement) pop()); } else { - jsFor.setBody(jsProgram.getEmptyStmt()); + jsFor.setBody(new JsEmpty(x.getSourceInfo())); } // increments @@ -892,7 +891,7 @@ if (x.getThenStmt() != null) { stmt.setThenStmt((JsStatement) pop()); // thenStmt } else { - stmt.setThenStmt(jsProgram.getEmptyStmt()); + stmt.setThenStmt(new JsEmpty(x.getSourceInfo())); } stmt.setIfExpr((JsExpression) pop()); // ifExpr @@ -1092,7 +1091,8 @@ } if (cur == null) { // the multi-expression was empty; use undefined - cur = jsProgram.getUndefinedLiteral(); + cur = new JsNameRef(x.getSourceInfo(), + JsRootScope.INSTANCE.getUndefined()); } push(cur); } @@ -1284,7 +1284,7 @@ if (x.getBody() != null) { stmt.setBody((JsStatement) pop()); // body } else { - stmt.setBody(jsProgram.getEmptyStmt()); + stmt.setBody(new JsEmpty(x.getSourceInfo())); } stmt.setCondition((JsExpression) pop()); // testExpr push(stmt); @@ -1593,8 +1593,7 @@ SourceInfo sourceInfo = program.createSourceInfoSynthetic( GenerateJavaScriptAST.class, "gwtOnLoad"); - JsName entryName = topScope.findExistingName("$entry"); - entryName.setObfuscatable(true); + JsName entryName = topScope.declareName("$entry"); JsVar entryVar = new JsVar(sourceInfo, entryName); JsInvocation registerEntryCall = new JsInvocation(sourceInfo); JsFunction registerEntryFunction = indexedFunctions.get("Impl.registerEntry"); @@ -1746,8 +1745,8 @@ * primitive with a modified prototype. */ JsNameRef rhs = prototype.makeRef(sourceInfo); - rhs.setQualifier(jsProgram.getRootScope().declareName("String").makeRef( - sourceInfo)); + rhs.setQualifier(JsRootScope.INSTANCE.findExistingUnobfuscatableName( + "String").makeRef(sourceInfo)); JsExpression tmpAsg = createAssignment(globalTemp.makeRef(sourceInfo), rhs); JsExprStmt tmpAsgStmt = tmpAsg.makeStmt(); @@ -2114,7 +2113,7 @@ this.jsProgram = jsProgram; topScope = jsProgram.getScope(); objectScope = jsProgram.getObjectScope(); - interfaceScope = new JsScope(objectScope, "Interfaces"); + interfaceScope = new JsNormalScope(objectScope, "Interfaces"); this.output = output; this.symbolTable = symbolTable;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptLiterals.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptLiterals.java index e9c55c2..fb50d79 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptLiterals.java +++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptLiterals.java
@@ -26,11 +26,14 @@ import com.google.gwt.dev.jjs.ast.JNullLiteral; import com.google.gwt.dev.jjs.ast.JStringLiteral; import com.google.gwt.dev.jjs.ast.JVisitor; +import com.google.gwt.dev.js.ast.JsBooleanLiteral; import com.google.gwt.dev.js.ast.JsExpression; import com.google.gwt.dev.js.ast.JsNameRef; +import com.google.gwt.dev.js.ast.JsNullLiteral; +import com.google.gwt.dev.js.ast.JsNumberLiteral; import com.google.gwt.dev.js.ast.JsObjectLiteral; -import com.google.gwt.dev.js.ast.JsProgram; import com.google.gwt.dev.js.ast.JsPropertyInitializer; +import com.google.gwt.dev.js.ast.JsStringLiteral; import com.google.gwt.dev.js.ast.JsVisitable; import com.google.gwt.lang.LongLib; @@ -44,36 +47,31 @@ */ public class GenerateJavaScriptLiterals extends JVisitor { - private final JsProgram program; private final Stack<JsVisitable> nodeStack = new Stack<JsVisitable>(); - public GenerateJavaScriptLiterals(JsProgram program) { - this.program = program; - } - @Override public final void endVisit(JBooleanLiteral x, Context ctx) { - push(x.getValue() ? program.getTrueLiteral() : program.getFalseLiteral()); + push(JsBooleanLiteral.get(x.getValue())); } @Override public final void endVisit(JCharLiteral x, Context ctx) { - push(program.getNumberLiteral(x.getSourceInfo(), x.getValue())); + push(new JsNumberLiteral(x.getSourceInfo(), x.getValue())); } @Override public final void endVisit(JDoubleLiteral x, Context ctx) { - push(program.getNumberLiteral(x.getSourceInfo(), x.getValue())); + push(new JsNumberLiteral(x.getSourceInfo(), x.getValue())); } @Override public final void endVisit(JFloatLiteral x, Context ctx) { - push(program.getNumberLiteral(x.getSourceInfo(), x.getValue())); + push(new JsNumberLiteral(x.getSourceInfo(), x.getValue())); } @Override public final void endVisit(JIntLiteral x, Context ctx) { - push(program.getNumberLiteral(x.getSourceInfo(), x.getValue())); + push(new JsNumberLiteral(x.getSourceInfo(), x.getValue())); } @Override @@ -85,9 +83,9 @@ JsExpression label0 = new JsNameRef(sourceInfo, "l"); JsExpression label1 = new JsNameRef(sourceInfo, "m"); JsExpression label2 = new JsNameRef(sourceInfo, "h"); - JsExpression value0 = program.getNumberLiteral(sourceInfo, intArray[0]); - JsExpression value1 = program.getNumberLiteral(sourceInfo, intArray[1]); - JsExpression value2 = program.getNumberLiteral(sourceInfo, intArray[2]); + JsExpression value0 = new JsNumberLiteral(sourceInfo, intArray[0]); + JsExpression value1 = new JsNumberLiteral(sourceInfo, intArray[1]); + JsExpression value2 = new JsNumberLiteral(sourceInfo, intArray[2]); inits.add(new JsPropertyInitializer(sourceInfo, label0, value0)); inits.add(new JsPropertyInitializer(sourceInfo, label1, value1)); inits.add(new JsPropertyInitializer(sourceInfo, label2, value2)); @@ -96,12 +94,12 @@ @Override public final void endVisit(JNullLiteral x, Context ctx) { - push(program.getNullLiteral()); + push(JsNullLiteral.INSTANCE); } @Override public final void endVisit(JStringLiteral x, Context ctx) { - push(program.getStringLiteral(x.getSourceInfo(), x.getValue())); + push(new JsStringLiteral(x.getSourceInfo(), x.getValue())); } @SuppressWarnings("unchecked")
diff --git a/dev/core/src/com/google/gwt/dev/js/JsInliner.java b/dev/core/src/com/google/gwt/dev/js/JsInliner.java index 5b56c97..aa97813 100644 --- a/dev/core/src/com/google/gwt/dev/js/JsInliner.java +++ b/dev/core/src/com/google/gwt/dev/js/JsInliner.java
@@ -26,9 +26,11 @@ import com.google.gwt.dev.js.ast.JsBlock; import com.google.gwt.dev.js.ast.JsBooleanLiteral; import com.google.gwt.dev.js.ast.JsCase; +import com.google.gwt.dev.js.ast.JsCatchScope; import com.google.gwt.dev.js.ast.JsConditional; import com.google.gwt.dev.js.ast.JsContext; import com.google.gwt.dev.js.ast.JsDefault; +import com.google.gwt.dev.js.ast.JsEmpty; import com.google.gwt.dev.js.ast.JsExprStmt; import com.google.gwt.dev.js.ast.JsExpression; import com.google.gwt.dev.js.ast.JsFor; @@ -48,9 +50,9 @@ import com.google.gwt.dev.js.ast.JsPostfixOperation; import com.google.gwt.dev.js.ast.JsPrefixOperation; import com.google.gwt.dev.js.ast.JsProgram; -import com.google.gwt.dev.js.ast.JsProgramFragment; import com.google.gwt.dev.js.ast.JsRegExp; import com.google.gwt.dev.js.ast.JsReturn; +import com.google.gwt.dev.js.ast.JsRootScope; import com.google.gwt.dev.js.ast.JsScope; import com.google.gwt.dev.js.ast.JsStatement; import com.google.gwt.dev.js.ast.JsStringLiteral; @@ -89,11 +91,9 @@ */ private static class AffectedBySideEffectsVisitor extends JsVisitor { private boolean affectedBySideEffects; - private final JsProgram program; private final JsScope safeScope; - public AffectedBySideEffectsVisitor(JsProgram program, JsScope safeScope) { - this.program = program; + public AffectedBySideEffectsVisitor(JsScope safeScope) { this.safeScope = safeScope; } @@ -125,7 +125,7 @@ public void endVisit(JsNameRef x, JsContext ctx) { if (x.getQualifier() == null && x.getName() != null) { // Special case the undefined literal. - if (x.getName() == program.getUndefinedLiteral().getName()) { + if (x.getName() == JsRootScope.INSTANCE.getUndefined()) { return; } // Locals in a safe scope are unaffected. @@ -423,7 +423,7 @@ return false; } else { // The return value from an XO function is never used - ctx.replaceMe(program.getNullLiteral()); + ctx.replaceMe(JsNullLiteral.INSTANCE); return false; } @@ -489,7 +489,7 @@ if (ctx.canRemove()) { ctx.removeMe(); } else { - ctx.replaceMe(program.getEmptyStmt()); + ctx.replaceMe(new JsEmpty(x.getSourceInfo())); } return false; @@ -604,8 +604,11 @@ * invocations occur. */ private static class EvaluationOrderVisitor extends JsVisitor { - public static final JsName THIS_NAME = (new JsScope("fake scope") { - }).declareName("this"); + /** + * A dummy name to represent 'this' refs. + */ + public static final JsName THIS_NAME = new JsCatchScope( + JsRootScope.INSTANCE, "this").getAllNames().next(); private boolean maintainsOrder = true; private final List<JsName> toEvaluate; @@ -777,7 +780,6 @@ private final Stack<JsFunction> functionStack = new Stack<JsFunction>(); private final InvocationCountingVisitor invocationCountingVisitor = new InvocationCountingVisitor(); private final Stack<List<JsName>> newLocalVariableStack = new Stack<List<JsName>>(); - private final JsProgram program; /** * A map containing the next integer to try as an identifier suffix for a @@ -791,7 +793,6 @@ private JsFunction programFunction; public InliningVisitor(JsProgram program) { - this.program = program; invocationCountingVisitor.accept(program); } @@ -856,7 +857,7 @@ if (ctx.canRemove()) { ctx.removeMe(); } else { - ctx.replaceMe(program.getEmptyStmt()); + ctx.replaceMe(new JsEmpty(x.getSourceInfo())); } } else if (x.getExpression() != statements.get(0).getExpression()) { @@ -969,7 +970,7 @@ } @Override - public void endVisit(JsProgramFragment x, JsContext ctx) { + public void endVisit(JsProgram x, JsContext ctx) { if (!functionStack.pop().equals(programFunction)) { throw new InternalCompilerException("Unexpected function popped"); } @@ -1003,9 +1004,8 @@ * top-level of the program. */ @Override - public boolean visit(JsProgramFragment x, JsContext ctx) { - programFunction = new JsFunction(program.getSourceInfo(), - program.getScope()); + public boolean visit(JsProgram x, JsContext ctx) { + programFunction = new JsFunction(x.getSourceInfo(), x.getScope()); programFunction.setBody(new JsBlock(x.getSourceInfo())); functionStack.push(programFunction); newLocalVariableStack.push(new ArrayList<JsName>()); @@ -1097,8 +1097,7 @@ * distinct objects, it would not be possible to substitute different * JsNameRefs at different call sites. */ - JsExpression h = hoistedExpression(program, statement, - localVariableNames); + JsExpression h = hoistedExpression(statement, localVariableNames); if (h == null) { return x; } @@ -1117,7 +1116,8 @@ * JsExprStmt. */ if (!sawReturnStatement) { - hoisted.add(program.getUndefinedLiteral()); + hoisted.add(new JsNameRef(x.getSourceInfo(), + JsRootScope.INSTANCE.getUndefined())); } assert (hoisted.size() > 0); @@ -1141,7 +1141,7 @@ } // Confirm that the expression conforms to the desired heuristics - if (!isInlinable(program, callerFunction, invokedFunction, thisExpr, + if (!isInlinable(callerFunction, invokedFunction, thisExpr, x.getArguments(), op)) { return x; } @@ -1618,8 +1618,8 @@ * the generated output. Increasing this number will allow larger sections of * code to be inlined, but at a cost of larger JS output. */ - private static final double MAX_COMPLEXITY_INCREASE = - Double.parseDouble(System.getProperty("gwt.jsinlinerRatio", "5.0")); + private static final double MAX_COMPLEXITY_INCREASE = Double.parseDouble(System.getProperty( + "gwt.jsinlinerRatio", "5.0")); /** * Static entry point used by JavaToJavaScriptCompiler. @@ -1637,8 +1637,8 @@ * The context parameter provides a scope in which local (and therefore * immutable) variables are defined. */ - private static boolean affectedBySideEffects(JsProgram program, - List<JsExpression> list, JsFunction context) { + private static boolean affectedBySideEffects(List<JsExpression> list, + JsFunction context) { /* * If the caller contains no nested functions, none of its locals can * possibly be affected by side effects. @@ -1647,8 +1647,7 @@ if (context != null && !containsNestedFunctions(context)) { safeScope = context.getScope(); } - AffectedBySideEffectsVisitor v = new AffectedBySideEffectsVisitor(program, - safeScope); + AffectedBySideEffectsVisitor v = new AffectedBySideEffectsVisitor(safeScope); v.acceptList(list); return v.affectedBySideEffects(); } @@ -1762,8 +1761,8 @@ * @return a JsExpression representing all expressions that would have been * evaluated by the statement */ - private static JsExpression hoistedExpression(JsProgram program, - JsStatement statement, List<JsName> localVariableNames) { + private static JsExpression hoistedExpression(JsStatement statement, + List<JsName> localVariableNames) { JsExpression expression; if (statement instanceof JsExprStmt) { // Extract the expression @@ -1775,7 +1774,8 @@ JsReturn ret = (JsReturn) statement; expression = ret.getExpr(); if (expression == null) { - expression = program.getUndefinedLiteral(); + expression = new JsNameRef(ret.getSourceInfo(), + JsRootScope.INSTANCE.getUndefined()); } } else if (statement instanceof JsVars) { @@ -1783,7 +1783,7 @@ JsVars vars = (JsVars) statement; // Rely on comma expression cleanup to remove this later. - expression = program.getNullLiteral(); + expression = JsNullLiteral.INSTANCE; for (JsVar var : vars) { // Record the locally-defined variable @@ -1854,9 +1854,8 @@ /** * Determine if a statement can be inlined into a call site. */ - private static boolean isInlinable(JsProgram program, JsFunction caller, - JsFunction callee, JsExpression thisExpr, List<JsExpression> arguments, - JsNode toInline) { + private static boolean isInlinable(JsFunction caller, JsFunction callee, + JsExpression thisExpr, List<JsExpression> arguments, JsNode toInline) { /* * This will happen with varargs-style JavaScript functions that rely on the @@ -1913,21 +1912,21 @@ * effects. This will determine how aggressively the parameters may be * reordered. */ - if (isVolatile(program, evalArgs, caller)) { + if (isVolatile(evalArgs, caller)) { /* * Determine the order in which the parameters must be evaluated. This * will vary between call sites, based on whether or not the invocation's * arguments can be repeated without ill effect. */ List<JsName> requiredOrder = new ArrayList<JsName>(); - if (thisExpr != null && isVolatile(program, thisExpr, callee)) { + if (thisExpr != null && isVolatile(thisExpr, callee)) { requiredOrder.add(EvaluationOrderVisitor.THIS_NAME); } for (int i = 0; i < arguments.size(); i++) { JsExpression e = arguments.get(i); JsParameter p = callee.getParameters().get(i); - if (isVolatile(program, e, callee)) { + if (isVolatile(e, callee)) { requiredOrder.add(p.getName()); } } @@ -1974,9 +1973,8 @@ * affected by side effects when evaluated within a particular function * context. */ - private static boolean isVolatile(JsProgram program, JsExpression e, - JsFunction context) { - return isVolatile(program, Collections.singletonList(e), context); + private static boolean isVolatile(JsExpression e, JsFunction context) { + return isVolatile(Collections.singletonList(e), context); } /** @@ -1984,10 +1982,8 @@ * affected by side effects when evaluated within a particular function * context. */ - private static boolean isVolatile(JsProgram program, List<JsExpression> list, - JsFunction context) { - return hasSideEffects(list) - || affectedBySideEffects(program, list, context); + private static boolean isVolatile(List<JsExpression> list, JsFunction context) { + return hasSideEffects(list) || affectedBySideEffects(list, context); } /**
diff --git a/dev/core/src/com/google/gwt/dev/js/JsParser.java b/dev/core/src/com/google/gwt/dev/js/JsParser.java index f1bdb2d..d3d81de 100644 --- a/dev/core/src/com/google/gwt/dev/js/JsParser.java +++ b/dev/core/src/com/google/gwt/dev/js/JsParser.java
@@ -15,7 +15,9 @@ */ package com.google.gwt.dev.js; +import com.google.gwt.dev.jjs.Correlation.Literal; import com.google.gwt.dev.jjs.SourceInfo; +import com.google.gwt.dev.jjs.SourceOrigin; import com.google.gwt.dev.js.ast.JsArrayAccess; import com.google.gwt.dev.js.ast.JsArrayLiteral; import com.google.gwt.dev.js.ast.JsBinaryOperation; @@ -27,8 +29,10 @@ import com.google.gwt.dev.js.ast.JsCatch; import com.google.gwt.dev.js.ast.JsConditional; import com.google.gwt.dev.js.ast.JsContinue; +import com.google.gwt.dev.js.ast.JsDebugger; import com.google.gwt.dev.js.ast.JsDefault; import com.google.gwt.dev.js.ast.JsDoWhile; +import com.google.gwt.dev.js.ast.JsEmpty; import com.google.gwt.dev.js.ast.JsExprStmt; import com.google.gwt.dev.js.ast.JsExpression; import com.google.gwt.dev.js.ast.JsFor; @@ -41,14 +45,16 @@ import com.google.gwt.dev.js.ast.JsNameRef; import com.google.gwt.dev.js.ast.JsNew; import com.google.gwt.dev.js.ast.JsNode; +import com.google.gwt.dev.js.ast.JsNullLiteral; +import com.google.gwt.dev.js.ast.JsNumberLiteral; import com.google.gwt.dev.js.ast.JsObjectLiteral; import com.google.gwt.dev.js.ast.JsParameter; import com.google.gwt.dev.js.ast.JsPostfixOperation; import com.google.gwt.dev.js.ast.JsPrefixOperation; -import com.google.gwt.dev.js.ast.JsProgram; import com.google.gwt.dev.js.ast.JsPropertyInitializer; import com.google.gwt.dev.js.ast.JsRegExp; import com.google.gwt.dev.js.ast.JsReturn; +import com.google.gwt.dev.js.ast.JsRootScope; import com.google.gwt.dev.js.ast.JsScope; import com.google.gwt.dev.js.ast.JsStatement; import com.google.gwt.dev.js.ast.JsStringLiteral; @@ -80,7 +86,7 @@ public static List<JsStatement> parse(SourceInfo rootSourceInfo, JsScope scope, Reader r) throws IOException, JsParserException { - return new JsParser(scope.getProgram()).parseImpl(rootSourceInfo, scope, r); + return new JsParser().parseImpl(rootSourceInfo, scope, r); } public static void parseInto(SourceInfo rootSourceInfo, JsScope scope, @@ -90,13 +96,10 @@ parentStmts.addAll(childStmts); } - private JsProgram program; - private final Stack<JsScope> scopeStack = new Stack<JsScope>(); private final Stack<SourceInfo> sourceInfoStack = new Stack<SourceInfo>(); - private JsParser(JsProgram program) { - this.program = program; + private JsParser() { } List<JsStatement> parseImpl(final SourceInfo rootSourceInfo, JsScope scope, @@ -155,9 +158,20 @@ // Rhino only reports line numbers for statement nodes, not expressions return parent; } - SourceInfo toReturn = program.createSourceInfo(lineno, parent.getFileName()); - toReturn.copyMissingCorrelationsFrom(parent); - return toReturn; + return parent.makeChild(SourceOrigin.create(lineno, parent.getFileName())); + } + + /** + * Force a distinct child to be created, so correlations can be added. + */ + private SourceInfo makeSourceInfoDistinct(Node node) { + SourceInfo parent = sourceInfoStack.peek(); + int lineno = node.getLineno(); + if (lineno == -1) { + // Rhino only reports line numbers for statement nodes, not expressions + lineno = parent.getStartLine(); + } + return parent.makeChild(SourceOrigin.create(lineno, parent.getFileName())); } private JsNode map(Node node) throws JsParserException { @@ -170,7 +184,7 @@ } case TokenStream.DEBUGGER: - return mapDebuggerStatement(); + return mapDebuggerStatement(node); case TokenStream.VOID: // VOID = nothing was parsed for this node @@ -236,10 +250,11 @@ case TokenStream.HOOK: return mapConditional(node); - case TokenStream.STRING: - return program.getStringLiteral( - sourceInfoStack.peek().makeChild(JsParser.class, - "JS String literal"), node.getString()); + case TokenStream.STRING: { + SourceInfo info = makeSourceInfoDistinct(node); + info.addCorrelation(info.getCorrelationFactory().by(Literal.JS_STRING)); + return new JsStringLiteral(info, node.getString()); + } case TokenStream.NUMBER: return mapNumber(node); @@ -484,10 +499,10 @@ } } - private JsStatement mapDebuggerStatement() { + private JsStatement mapDebuggerStatement(Node node) { // Calls an optional method to invoke the debugger. // - return program.getDebuggerStmt(); + return new JsDebugger(makeSourceInfo(node)); } private JsExpression mapDeleteProp(Node node) throws JsParserException { @@ -597,6 +612,7 @@ Node fromIncr = fromTest.getNext(); Node fromBody = fromIncr.getNext(); + SourceInfo info = makeSourceInfo(forNode); if (fromBody == null) { // This could be a "for...in" structure. // We could based on the different child layout. @@ -612,7 +628,7 @@ Node fromIterVarName = fromIter.getFirstChild(); String fromName = fromIterVarName.getString(); JsName toName = getScope().declareName(fromName); - toForIn = new JsForIn(makeSourceInfo(forNode), toName); + toForIn = new JsForIn(info, toName); Node fromIterInit = fromIterVarName.getFirstChild(); if (fromIterInit != null) { // That has an initializer expression (useful only for side effects). @@ -622,7 +638,7 @@ } else { // An unnamed iterator var. // - toForIn = new JsForIn(makeSourceInfo(forNode)); + toForIn = new JsForIn(info); toForIn.setIterExpr(mapExpression(fromIter)); } toForIn.setObjExpr(mapExpression(fromObjExpr)); @@ -633,14 +649,14 @@ if (bodyStmt != null) { toForIn.setBody(bodyStmt); } else { - toForIn.setBody(program.getEmptyStmt()); + toForIn.setBody(new JsEmpty(info)); } return toForIn; } else { // Regular ol' for loop. // - JsFor toFor = new JsFor(makeSourceInfo(forNode)); + JsFor toFor = new JsFor(info); // The first item is either an expression or a JsVars. JsNode initThingy = map(fromInit); @@ -659,7 +675,7 @@ if (bodyStmt != null) { toFor.setBody(bodyStmt); } else { - toFor.setBody(program.getEmptyStmt()); + toFor.setBody(new JsEmpty(info)); } return toFor; } @@ -821,7 +837,8 @@ } private JsExpression mapNumber(Node numberNode) { - return program.getNumberLiteral(numberNode.getDouble()); + return new JsNumberLiteral(makeSourceInfo(numberNode), + numberNode.getDouble()); } private JsExpression mapObjectLit(Node objLitNode) throws JsParserException { @@ -887,16 +904,20 @@ return new JsThisRef(makeSourceInfo(node)); case TokenStream.TRUE: - return program.getTrueLiteral(); + return JsBooleanLiteral.TRUE; case TokenStream.FALSE: - return program.getFalseLiteral(); + return JsBooleanLiteral.FALSE; case TokenStream.NULL: - return program.getNullLiteral(); + return JsNullLiteral.INSTANCE; - case TokenStream.UNDEFINED: - return program.getUndefinedLiteral(); + case TokenStream.UNDEFINED: { + SourceInfo info = makeSourceInfoDistinct(node); + info.addCorrelation(info.getCorrelationFactory().by( + Literal.JS_UNDEFINED)); + return new JsNameRef(info, JsRootScope.INSTANCE.getUndefined()); + } default: throw createParserException("Unknown primary: " + node.getIntDatum(), @@ -1017,7 +1038,7 @@ } else { // When map() returns null, we return an empty statement. // - return program.getEmptyStmt(); + return new JsEmpty(makeSourceInfo(nodeStmt)); } }
diff --git a/dev/core/src/com/google/gwt/dev/js/JsStackEmulator.java b/dev/core/src/com/google/gwt/dev/js/JsStackEmulator.java index 26bcfbc..35633c3 100644 --- a/dev/core/src/com/google/gwt/dev/js/JsStackEmulator.java +++ b/dev/core/src/com/google/gwt/dev/js/JsStackEmulator.java
@@ -27,6 +27,7 @@ import com.google.gwt.dev.js.ast.JsBinaryOperation; import com.google.gwt.dev.js.ast.JsBinaryOperator; import com.google.gwt.dev.js.ast.JsBlock; +import com.google.gwt.dev.js.ast.JsBooleanLiteral; import com.google.gwt.dev.js.ast.JsCatch; import com.google.gwt.dev.js.ast.JsContext; import com.google.gwt.dev.js.ast.JsExprStmt; @@ -39,10 +40,13 @@ import com.google.gwt.dev.js.ast.JsNameRef; import com.google.gwt.dev.js.ast.JsNew; import com.google.gwt.dev.js.ast.JsNode; +import com.google.gwt.dev.js.ast.JsNullLiteral; +import com.google.gwt.dev.js.ast.JsNumberLiteral; import com.google.gwt.dev.js.ast.JsPostfixOperation; import com.google.gwt.dev.js.ast.JsPrefixOperation; import com.google.gwt.dev.js.ast.JsProgram; import com.google.gwt.dev.js.ast.JsReturn; +import com.google.gwt.dev.js.ast.JsRootScope; import com.google.gwt.dev.js.ast.JsStatement; import com.google.gwt.dev.js.ast.JsStringLiteral; import com.google.gwt.dev.js.ast.JsThrow; @@ -50,9 +54,9 @@ import com.google.gwt.dev.js.ast.JsUnaryOperation; import com.google.gwt.dev.js.ast.JsUnaryOperator; import com.google.gwt.dev.js.ast.JsVars; +import com.google.gwt.dev.js.ast.JsVars.JsVar; import com.google.gwt.dev.js.ast.JsVisitor; import com.google.gwt.dev.js.ast.JsWhile; -import com.google.gwt.dev.js.ast.JsVars.JsVar; import com.google.gwt.dev.util.collect.Lists; import com.google.gwt.dev.util.collect.Maps; @@ -278,7 +282,7 @@ // There is a finally block, so we need to set the early-exit flag JsBinaryOperation asg = new JsBinaryOperation(x.getSourceInfo(), JsBinaryOperator.ASG, earlyExitRef(outerFinallyBlock), - program.getBooleanLiteral(true)); + JsBooleanLiteral.get(true)); if (x.getExpr() == null) { if (ctx.canInsert()) { // exitingEarly = true; return; @@ -507,7 +511,7 @@ */ private JsExpression pop(SourceInfo info) { JsBinaryOperation sub = new JsBinaryOperation(info, JsBinaryOperator.SUB, - stackIndexRef(info), program.getNumberLiteral(1)); + stackIndexRef(info), new JsNumberLiteral(info, 1)); JsBinaryOperation op = new JsBinaryOperation(info, JsBinaryOperator.ASG, stackDepth.makeRef(info), sub); return op; @@ -525,7 +529,7 @@ JsExpression currentFunctionRef; if (currentFunction.getName() == null) { // Anonymous - currentFunctionRef = program.getNullLiteral(); + currentFunctionRef = JsNullLiteral.INSTANCE; } else { currentFunctionRef = currentFunction.getName().makeRef(info); } @@ -737,11 +741,11 @@ "Synthetic location data"); // ($locations[stackIndex] = fileName + lineNumber, x) - JsExpression location = program.getStringLiteral(info, + JsExpression location = new JsStringLiteral(info, String.valueOf(lastLine = info.getStartLine())); if (recordFileNames) { // 'fileName:' + lineNumber - JsStringLiteral stringLit = program.getStringLiteral(info, + JsStringLiteral stringLit = new JsStringLiteral(info, baseName(lastFile = info.getFileName()) + ":"); location = new JsBinaryOperation(info, JsBinaryOperator.ADD, stringLit, location); @@ -770,13 +774,10 @@ * with references to our locally-defined, obfuscatable names. */ private class ReplaceUnobfuscatableNames extends JsModVisitor { - private final JsName rootLineNumbers = program.getRootScope().findExistingUnobfuscatableName( - "$location"); // See JsRootScope for the definition of these names - private final JsName rootStack = program.getRootScope().findExistingUnobfuscatableName( - "$stack"); - private final JsName rootStackDepth = program.getRootScope().findExistingUnobfuscatableName( - "$stackDepth"); + private final JsName rootLineNumbers = JsRootScope.INSTANCE.findExistingUnobfuscatableName("$location"); + private final JsName rootStack = JsRootScope.INSTANCE.findExistingUnobfuscatableName("$stack"); + private final JsName rootStackDepth = JsRootScope.INSTANCE.findExistingUnobfuscatableName("$stackDepth"); @Override public void endVisit(JsNameRef x, JsContext ctx) { @@ -896,7 +897,7 @@ JsVar stackVar = new JsVar(info, stack); stackVar.setInitExpr(new JsArrayLiteral(info)); JsVar stackDepthVar = new JsVar(info, stackDepth); - stackDepthVar.setInitExpr(program.getNumberLiteral(info, -1)); + stackDepthVar.setInitExpr(new JsNumberLiteral(info, (-1))); JsVar lineNumbersVar = new JsVar(info, lineNumbers); lineNumbersVar.setInitExpr(new JsArrayLiteral(info));
diff --git a/dev/core/src/com/google/gwt/dev/js/JsStaticEval.java b/dev/core/src/com/google/gwt/dev/js/JsStaticEval.java index aaa9db5..f44b733 100644 --- a/dev/core/src/com/google/gwt/dev/js/JsStaticEval.java +++ b/dev/core/src/com/google/gwt/dev/js/JsStaticEval.java
@@ -28,6 +28,7 @@ import com.google.gwt.dev.js.ast.JsContext; import com.google.gwt.dev.js.ast.JsContinue; import com.google.gwt.dev.js.ast.JsDoWhile; +import com.google.gwt.dev.js.ast.JsEmpty; import com.google.gwt.dev.js.ast.JsExprStmt; import com.google.gwt.dev.js.ast.JsExpression; import com.google.gwt.dev.js.ast.JsFor; @@ -291,7 +292,7 @@ if (ctx.canRemove()) { ctx.removeMe(); } else { - ctx.replaceMe(program.getEmptyStmt()); + ctx.replaceMe(new JsEmpty(x.getSourceInfo())); } } } @@ -623,7 +624,7 @@ // "undefined" is not a JsValueLiteral, so the only way // the result can be true is if exp is itself a JsNullLiteral boolean result = exp instanceof JsNullLiteral; - return program.getBooleanLiteral(result); + return JsBooleanLiteral.get(result); } // no simplification made @@ -640,7 +641,7 @@ // "undefined" is not a JsValueLiteral, so the only way // the result can be false is if exp is itself a JsNullLiteral boolean result = !(exp instanceof JsNullLiteral); - return program.getBooleanLiteral(result); + return JsBooleanLiteral.get(result); } // no simplification made @@ -653,18 +654,19 @@ private void trySimplifyAdd(JsExpression original, JsExpression arg1, JsExpression arg2, JsContext ctx) { if (arg1 instanceof JsValueLiteral && arg2 instanceof JsValueLiteral) { + SourceInfo info = original.getSourceInfo(); // case: number + number if (arg1 instanceof JsNumberLiteral && arg2 instanceof JsNumberLiteral) { double value = ((JsNumberLiteral) arg1).getValue() + ((JsNumberLiteral) arg2).getValue(); - ctx.replaceMe(program.getNumberLiteral(value)); + ctx.replaceMe(new JsNumberLiteral(info, value)); } else { // cases: number + string or string + number StringBuilder result = new StringBuilder(); if (appendLiteral(result, (JsValueLiteral) arg1) && appendLiteral(result, (JsValueLiteral) arg2)) { - ctx.replaceMe(program.getStringLiteral(original.getSourceInfo(), - result.toString())); + info.merge(arg1.getSourceInfo(), arg2.getSourceInfo()); + ctx.replaceMe(new JsStringLiteral(info, result.toString())); } } }
diff --git a/dev/core/src/com/google/gwt/dev/js/JsSymbolResolver.java b/dev/core/src/com/google/gwt/dev/js/JsSymbolResolver.java index 1f0c050..3ae0308 100644 --- a/dev/core/src/com/google/gwt/dev/js/JsSymbolResolver.java +++ b/dev/core/src/com/google/gwt/dev/js/JsSymbolResolver.java
@@ -37,7 +37,7 @@ name = getScope().findExistingName(ident); if (name == null) { // No clue what this is; create a new unobfuscatable name - name = program.getRootScope().declareName(ident); + name = program.getScope().declareName(ident); name.setObfuscatable(false); } } else {
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsBooleanLiteral.java b/dev/core/src/com/google/gwt/dev/js/ast/JsBooleanLiteral.java index e254270..24fc9c1 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsBooleanLiteral.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsBooleanLiteral.java
@@ -16,16 +16,26 @@ package com.google.gwt.dev.js.ast; import com.google.gwt.dev.jjs.SourceInfo; +import com.google.gwt.dev.jjs.SourceOrigin; /** * Represents a JavaScript literal boolean expression. */ public final class JsBooleanLiteral extends JsValueLiteral { + public static final JsBooleanLiteral FALSE = new JsBooleanLiteral( + SourceOrigin.UNKNOWN, false); + + public static final JsBooleanLiteral TRUE = new JsBooleanLiteral( + SourceOrigin.UNKNOWN, true); + + public static JsBooleanLiteral get(boolean value) { + return value ? TRUE : FALSE; + } + private final boolean value; - // Should be interned by JsProgram - JsBooleanLiteral(SourceInfo sourceInfo, boolean value) { + private JsBooleanLiteral(SourceInfo sourceInfo, boolean value) { super(sourceInfo); this.value = value; } @@ -56,4 +66,8 @@ v.visit(this, ctx); v.endVisit(this, ctx); } + + private Object readResolve() { + return get(value); + } }
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsCatchScope.java b/dev/core/src/com/google/gwt/dev/js/ast/JsCatchScope.java index 1791fc5..542d398 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsCatchScope.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsCatchScope.java
@@ -15,14 +15,14 @@ */ package com.google.gwt.dev.js.ast; +import java.util.Collections; import java.util.Iterator; -import java.util.NoSuchElementException; /** * A special scope used only for catch blocks. It only holds a single symbol: * the catch argument's name. */ -public class JsCatchScope extends JsScope { +public class JsCatchScope extends JsNestingScope { private final JsName name; @@ -32,45 +32,14 @@ } @Override - public JsName declareName(String ident) { - // Declare into parent scope! - return getParent().declareName(ident); - } - - @Override - public JsName declareName(String ident, String shortIdent) { - // Declare into parent scope! - return getParent().declareName(ident, shortIdent); - } - - @Override public Iterator<JsName> getAllNames() { - return new Iterator<JsName>() { - private boolean didIterate = false; - - public boolean hasNext() { - return !didIterate; - } - - public JsName next() { - if (didIterate) { - throw new NoSuchElementException(); - } - didIterate = true; - return name; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - }; + return Collections.singleton(name).iterator(); } @Override protected JsName doCreateName(String ident, String shortIdent) { - throw new UnsupportedOperationException( - "Cannot create a name in a catch scope"); + // Declare into parent scope! + return getParent().declareName(ident, shortIdent); } @Override
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsEmpty.java b/dev/core/src/com/google/gwt/dev/js/ast/JsEmpty.java index 00a5b6f..4727008 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsEmpty.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsEmpty.java
@@ -22,8 +22,7 @@ */ public class JsEmpty extends JsStatement { - // Interned by JsProgram - JsEmpty(SourceInfo sourceInfo) { + public JsEmpty(SourceInfo sourceInfo) { super(sourceInfo); }
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsFunction.java b/dev/core/src/com/google/gwt/dev/js/ast/JsFunction.java index 959470c..74f211f 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsFunction.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsFunction.java
@@ -68,7 +68,7 @@ setName(name); String scopeName = (name == null) ? "<anonymous>" : name.getIdent(); scopeName = "function " + scopeName; - this.scope = new JsScope(parent, scopeName); + this.scope = new JsNormalScope(parent, scopeName); } public JsBlock getBody() {
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsNameRef.java b/dev/core/src/com/google/gwt/dev/js/ast/JsNameRef.java index 58a7a8c..4bde74d 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsNameRef.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsNameRef.java
@@ -89,10 +89,7 @@ @Override public boolean isDefinitelyNull() { - if (name != null) { - return (name.getEnclosing().getProgram().getUndefinedLiteral().getName() == name); - } - return false; + return name == JsRootScope.INSTANCE.getUndefined(); } @Override
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsNestingScope.java b/dev/core/src/com/google/gwt/dev/js/ast/JsNestingScope.java new file mode 100644 index 0000000..36b83e7 --- /dev/null +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsNestingScope.java
@@ -0,0 +1,74 @@ +/* + * Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.dev.js.ast; + +import com.google.gwt.dev.util.collect.Lists; + +import java.io.Serializable; +import java.util.List; + +/** + * A normal scope that has a parent and children. + */ +public abstract class JsNestingScope extends JsScope implements Serializable { + + /** + * Transient because children will add themselves to the parent after + * deserialization. + */ + private transient List<JsScope> children = Lists.create(); + + private final JsScope parent; + + /** + * Create a scope with parent. + */ + public JsNestingScope(JsScope parent, String description) { + super(description); + assert (parent != null); + this.parent = parent; + parent.addChild(this); + } + + /** + * Returns a list of this scope's child scopes. + */ + @Override + public final List<JsScope> getChildren() { + return children; + } + + /** + * Returns the parent scope of this scope, or <code>null</code> if this is the + * root scope. + */ + @Override + public final JsScope getParent() { + return parent; + } + + @Override + protected final void addChild(JsScope child) { + children = Lists.add(children, child); + } + + protected Object readResolve() { + children = Lists.create(); + parent.addChild(this); + return this; + } + +}
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsNormalScope.java b/dev/core/src/com/google/gwt/dev/js/ast/JsNormalScope.java new file mode 100644 index 0000000..ce4dcf6 --- /dev/null +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsNormalScope.java
@@ -0,0 +1,70 @@ +/* + * Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.dev.js.ast; + +import com.google.gwt.dev.util.StringInterner; +import com.google.gwt.dev.util.collect.Maps; + +import java.io.Serializable; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; + +/** + * A normal scope that has a parent and children. + */ +public class JsNormalScope extends JsNestingScope implements Serializable { + + private Map<String, JsName> names = Collections.emptyMap(); + + /** + * Create a scope with parent. + */ + public JsNormalScope(JsScope parent, String description) { + super(parent, description); + } + + /** + * Returns an iterator for all the names defined by this scope. + */ + @Override + public Iterator<JsName> getAllNames() { + return names.values().iterator(); + } + + /** + * Creates a new name in this scope. + */ + @Override + protected JsName doCreateName(String ident, String shortIdent) { + ident = StringInterner.get().intern(ident); + shortIdent = StringInterner.get().intern(shortIdent); + JsName name = new JsName(this, ident, shortIdent); + names = Maps.putOrdered(names, ident, name); + return name; + } + + /** + * Attempts to find the name object for the specified ident, searching in this + * scope only. + * + * @return <code>null</code> if the identifier has no associated name + */ + @Override + protected JsName findExistingNameNoRecurse(String ident) { + return names.get(ident); + } +}
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsNullLiteral.java b/dev/core/src/com/google/gwt/dev/js/ast/JsNullLiteral.java index dba3966..2774635 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsNullLiteral.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsNullLiteral.java
@@ -16,14 +16,17 @@ package com.google.gwt.dev.js.ast; import com.google.gwt.dev.jjs.SourceInfo; +import com.google.gwt.dev.jjs.SourceOrigin; /** * A JavaScript null literal. */ public final class JsNullLiteral extends JsValueLiteral { - // Should only be instantiated in JsProgram - JsNullLiteral(SourceInfo sourceInfo) { + public static final JsNullLiteral INSTANCE = new JsNullLiteral( + SourceOrigin.UNKNOWN); + + private JsNullLiteral(SourceInfo sourceInfo) { super(sourceInfo); } @@ -49,4 +52,12 @@ v.visit(this, ctx); v.endVisit(this, ctx); } + + /** + * Note, if this ever becomes not-a-singleton, we'll need to check the + * SourceInfo == SourceOrigin.UNKNOWN. + */ + private Object readResolve() { + return INSTANCE; + } }
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsNumberLiteral.java b/dev/core/src/com/google/gwt/dev/js/ast/JsNumberLiteral.java index 90026ac..df3508c 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsNumberLiteral.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsNumberLiteral.java
@@ -24,8 +24,7 @@ private final double value; - // Should be interned by JsProgram - JsNumberLiteral(SourceInfo sourceInfo, double value) { + public JsNumberLiteral(SourceInfo sourceInfo, double value) { super(sourceInfo); this.value = value; }
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsProgram.java b/dev/core/src/com/google/gwt/dev/js/ast/JsProgram.java index 9ab9e27..a05967b 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsProgram.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsProgram.java
@@ -16,10 +16,9 @@ package com.google.gwt.dev.js.ast; import com.google.gwt.dev.jjs.CorrelationFactory; +import com.google.gwt.dev.jjs.CorrelationFactory.DummyCorrelationFactory; import com.google.gwt.dev.jjs.SourceInfo; import com.google.gwt.dev.jjs.SourceOrigin; -import com.google.gwt.dev.jjs.Correlation.Axis; -import com.google.gwt.dev.jjs.Correlation.Literal; import java.util.HashMap; import java.util.Map; @@ -31,39 +30,16 @@ private final CorrelationFactory correlator; - private final JsStatement debuggerStmt; - - private final JsEmpty emptyStmt; - - private final JsBooleanLiteral falseLiteral; - private JsProgramFragment[] fragments; - /** - * The root intrinsic source info. - */ - private final SourceInfo intrinsic; - private final Map<String, JsFunction> indexedFunctions = new HashMap<String, JsFunction>(); - private final JsNullLiteral nullLiteral; - - private final Map<Double, JsNumberLiteral> numberLiteralMap = new HashMap<Double, JsNumberLiteral>(); - private final JsScope objectScope; - private final JsRootScope rootScope; - - private final Map<String, JsStringLiteral> stringLiteralMap = new HashMap<String, JsStringLiteral>(); - - private final SourceInfo stringPoolSourceInfo; - private final JsScope topScope; - private final JsBooleanLiteral trueLiteral; - public JsProgram() { - this(new CorrelationFactory.DummyCorrelationFactory()); + this(DummyCorrelationFactory.INSTANCE); } /** @@ -79,26 +55,16 @@ JsProgram.class.getName()))); this.correlator = correlator; - intrinsic = createSourceInfo(0, getClass().getName()); - rootScope = new JsRootScope(this); - topScope = new JsScope(rootScope, "Global"); - objectScope = new JsScope(rootScope, "Object"); + topScope = new JsNormalScope(JsRootScope.INSTANCE, "Global"); + objectScope = new JsNormalScope(JsRootScope.INSTANCE, "Object"); setFragmentCount(1); + } - debuggerStmt = new JsDebugger(createLiteralSourceInfo("debugger statement")); - emptyStmt = new JsEmpty(createLiteralSourceInfo("Empty statement")); - falseLiteral = new JsBooleanLiteral(createLiteralSourceInfo( - "false literal", Literal.JS_BOOLEAN), false); - nullLiteral = new JsNullLiteral(createLiteralSourceInfo("null literal", - Literal.JS_NULL)); - trueLiteral = new JsBooleanLiteral(createLiteralSourceInfo("true literal", - Literal.JS_BOOLEAN), true); - - trueLiteral.getSourceInfo().addCorrelation( - correlator.by(Literal.JS_BOOLEAN)); - stringPoolSourceInfo = createLiteralSourceInfo("String pool", - Literal.JS_STRING); + public SourceInfo createSourceInfo(int startPos, int endPos, int startLine, + String fileName) { + return correlator.makeSourceInfo(SourceOrigin.create(startPos, endPos, + startLine, fileName)); } public SourceInfo createSourceInfo(int lineNumber, String location) { @@ -110,31 +76,6 @@ return createSourceInfo(0, caller.getName()).makeChild(caller, description); } - public JsBooleanLiteral getBooleanLiteral(boolean truth) { - if (truth) { - return getTrueLiteral(); - } - return getFalseLiteral(); - } - - /** - * Gets the {@link JsStatement} to use whenever parsed source include a - * <code>debugger</code> statement. - * - * @see #setDebuggerStmt(JsStatement) - */ - public JsStatement getDebuggerStmt() { - return debuggerStmt; - } - - public JsEmpty getEmptyStmt() { - return emptyStmt; - } - - public JsBooleanLiteral getFalseLiteral() { - return falseLiteral; - } - public JsBlock getFragmentBlock(int fragment) { if (fragment < 0 || fragment >= fragments.length) { throw new IllegalArgumentException("Invalid fragment: " + fragment); @@ -157,56 +98,11 @@ return indexedFunctions.get(name); } - public JsNullLiteral getNullLiteral() { - return nullLiteral; - } - - public JsNumberLiteral getNumberLiteral(double value) { - return getNumberLiteral(null, value); - } - - public JsNumberLiteral getNumberLiteral(SourceInfo info, double value) { - /* - * This method only canonicalizes number literals when we don't have an - * incoming SourceInfo so that we can distinguish int-0 from double-0 in the - * analysis. - */ - if (info == null) { - JsNumberLiteral lit = numberLiteralMap.get(value); - if (lit == null) { - info = createSourceInfoSynthetic(JsProgram.class, "Number literal " - + value); - info.addCorrelation(correlator.by(Literal.JS_NUMBER)); - lit = new JsNumberLiteral(info, value); - numberLiteralMap.put(value, lit); - } - - return lit; - } else { - // Only add a JS_NUMBER if no literal correlation present: e.g. Java int - if (info.getPrimaryCorrelation(Axis.LITERAL) == null) { - // Don't mutate incoming SourceInfo - info = info.makeChild(JsProgram.class, "Number literal " + value); - info.addCorrelation(correlator.by(Literal.JS_NUMBER)); - } - return new JsNumberLiteral(info, value); - } - } - public JsScope getObjectScope() { return objectScope; } /** - * Gets the quasi-mythical root scope. This is not the same as the top scope; - * all unresolvable identifiers wind up here, because they are considered - * external to the program. - */ - public JsRootScope getRootScope() { - return rootScope; - } - - /** * Gets the top level scope. This is the scope of all the statements in the * main program. */ @@ -214,31 +110,6 @@ return topScope; } - /** - * Creates or retrieves a JsStringLiteral from an interned object pool. - */ - public JsStringLiteral getStringLiteral(SourceInfo sourceInfo, String value) { - JsStringLiteral lit = stringLiteralMap.get(value); - if (lit == null) { - lit = new JsStringLiteral(stringPoolSourceInfo.makeChild(JsProgram.class, - "String literal: " + value), value); - stringLiteralMap.put(value, lit); - } - lit.getSourceInfo().merge(sourceInfo); - return lit; - } - - public JsBooleanLiteral getTrueLiteral() { - return trueLiteral; - } - - public JsNameRef getUndefinedLiteral() { - SourceInfo info = createSourceInfoSynthetic(JsProgram.class, - "undefined reference"); - info.addCorrelation(correlator.by(Literal.JS_UNDEFINED)); - return rootScope.findExistingName("undefined").makeRef(info); - } - public void setFragmentCount(int fragments) { this.fragments = new JsProgramFragment[fragments]; for (int i = 0; i < fragments; i++) { @@ -260,14 +131,4 @@ } v.endVisit(this, ctx); } - - private SourceInfo createLiteralSourceInfo(String description) { - return intrinsic.makeChild(getClass(), description); - } - - private SourceInfo createLiteralSourceInfo(String description, Literal literal) { - SourceInfo child = createLiteralSourceInfo(description); - child.addCorrelation(correlator.by(literal)); - return child; - } }
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsRootName.java b/dev/core/src/com/google/gwt/dev/js/ast/JsRootName.java new file mode 100644 index 0000000..d32582a --- /dev/null +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsRootName.java
@@ -0,0 +1,61 @@ +/* + * Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.dev.js.ast; + +import java.io.Serializable; + +/** + * A well-known name in the root scope. + */ +public class JsRootName extends JsName { + + private static class SerializedForm implements Serializable { + private final String ident; + + public SerializedForm(String ident) { + this.ident = ident; + } + + private Object readResolve() { + return JsRootScope.INSTANCE.findExistingName(ident); + } + } + + JsRootName(JsRootScope rootScope, String ident) { + super(rootScope, ident, ident); + super.setObfuscatable(false); + } + + @Override + public void setObfuscatable(boolean isObfuscatable) { + throw new UnsupportedOperationException("Root names are immutable"); + } + + @Override + public void setShortIdent(String shortIdent) { + throw new UnsupportedOperationException("Root names are immutable"); + } + + @Override + public void setStaticRef(JsNode node) { + throw new UnsupportedOperationException("Root names are immutable"); + } + + private Object writeReplace() { + return new SerializedForm(getIdent()); + } + +}
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsRootScope.java b/dev/core/src/com/google/gwt/dev/js/ast/JsRootScope.java index 325f62e..6f1dfc1 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsRootScope.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsRootScope.java
@@ -15,336 +15,383 @@ */ package com.google.gwt.dev.js.ast; +import com.google.gwt.dev.util.collect.Lists; + +import java.io.Serializable; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + /** - * The root scope is the parent of every scope. All identifiers in this scope - * are not obfuscatable. + * The root scope is the parent of every scope, it contains a list of browser + * built-in identifiers that we should recognize and never obfuscate into. */ public final class JsRootScope extends JsScope { + /* + * NOTE: the startup sequence for this class is a bit tricky. + */ - private final JsProgram program; + private static class SerializedForm implements Serializable { + private Object readResolve() { + return JsRootScope.INSTANCE; + } + } - public JsRootScope(JsProgram program) { + public static final JsRootScope INSTANCE; + + private static final String[] COMMON_BUILTINS = new String[]{ + // 15.1.1 Value Properties of the Global Object + "NaN", + "Infinity", + "undefined", + + // 15.1.2 Function Properties of the Global Object + "eval", + "parseInt", + "parseFloat", + "isNan", + "isFinite", + + // 15.1.3 URI Handling Function Properties + "decodeURI", + "decodeURIComponent", + "encodeURI", + "encodeURIComponent", + + // 15.1.4 Constructor Properties of the Global Object + "Object", + "Function", + "Array", + "String", + "Boolean", + "Number", + "Date", + "RegExp", + "Error", + "EvalError", + "RangeError", + "ReferenceError", + "SyntaxError", + "TypeError", + "URIError", + + // 15.1.5 Other Properties of the Global Object + "Math", + + // 10.1.6 Activation Object + "arguments", + + // B.2 Additional Properties (non-normative) + "escape", + "unescape", + + // Window props (https://developer.mozilla.org/en/DOM/window) + "applicationCache", + "closed", + "Components", + "content", + "controllers", + "crypto", + "defaultStatus", + "dialogArguments", + "directories", + "document", + "frameElement", + "frames", + "fullScreen", + "globalStorage", + "history", + "innerHeight", + "innerWidth", + "length", + "location", + "locationbar", + "localStorage", + "menubar", + "mozInnerScreenX", + "mozInnerScreenY", + "mozScreenPixelsPerCssPixel", + "name", + "navigator", + "opener", + "outerHeight", + "outerWidth", + "pageXOffset", + "pageYOffset", + "parent", + "personalbar", + "pkcs11", + "returnValue", + "screen", + "scrollbars", + "scrollMaxX", + "scrollMaxY", + "self", + "sessionStorage", + "sidebar", + "status", + "statusbar", + "toolbar", + "top", + "window", + + // Window methods (https://developer.mozilla.org/en/DOM/window) + "alert", + "addEventListener", + "atob", + "back", + "blur", + "btoa", + "captureEvents", + "clearInterval", + "clearTimeout", + "close", + "confirm", + "disableExternalCapture", + "dispatchEvent", + "dump", + "enableExternalCapture", + "escape", + "find", + "focus", + "forward", + "GeckoActiveXObject", + "getAttention", + "getAttentionWithCycleCount", + "getComputedStyle", + "getSelection", + "home", + "maximize", + "minimize", + "moveBy", + "moveTo", + "open", + "openDialog", + "postMessage", + "print", + "prompt", + "QueryInterface", + "releaseEvents", + "removeEventListener", + "resizeBy", + "resizeTo", + "restore", + "routeEvent", + "scroll", + "scrollBy", + "scrollByLines", + "scrollByPages", + "scrollTo", + "setInterval", + "setResizeable", + "setTimeout", + "showModalDialog", + "sizeToContent", + "stop", + "uuescape", + "updateCommands", + "XPCNativeWrapper", + "XPCSafeJSOjbectWrapper", + + // Mozilla Window event handlers, same cite + "onabort", + "onbeforeunload", + "onchange", + "onclick", + "onclose", + "oncontextmenu", + "ondragdrop", + "onerror", + "onfocus", + "onhashchange", + "onkeydown", + "onkeypress", + "onkeyup", + "onload", + "onmousedown", + "onmousemove", + "onmouseout", + "onmouseover", + "onmouseup", + "onmozorientation", + "onpaint", + "onreset", + "onresize", + "onscroll", + "onselect", + "onsubmit", + "onunload", + + // Safari Web Content Guide + // http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/SafariWebContent.pdf + // WebKit Window member data, from WebKit DOM Reference + // (http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/WebKitDOMRef/DOMWindow_idl/Classes/DOMWindow/index.html) + // TODO(fredsa) Many, many more functions and member data to add + "ontouchcancel", + "ontouchend", + "ontouchmove", + "ontouchstart", + "ongesturestart", + "ongesturechange", + "ongestureend", + + // extra window methods + "uneval", + + // keywords https://developer.mozilla.org/en/New_in_JavaScript_1.7, + // https://developer.mozilla.org/en/New_in_JavaScript_1.8.1 + "getPrototypeOf", + "let", + + // "future reserved words" + "abstract", + "int", + "short", + "boolean", + "interface", + "static", + "byte", + "long", + "char", + "final", + "native", + "synchronized", + "float", + "package", + "throws", + "goto", + "private", + "transient", + "implements", + "protected", + "volatile", + "double", + "public", + + // IE methods + // (http://msdn.microsoft.com/en-us/library/ms535873(VS.85).aspx#) + "attachEvent", + "clientInformation", + "clipboardData", + "createPopup", + "dialogHeight", + "dialogLeft", + "dialogTop", + "dialogWidth", + "onafterprint", + "onbeforedeactivate", + "onbeforeprint", + "oncontrolselect", + "ondeactivate", + "onhelp", + "onresizeend", + + // Common browser-defined identifiers not defined in ECMAScript + "event", + "external", + "Debug", + "Enumerator", + "Global", + "Image", + "ActiveXObject", + "VBArray", + "Components", + + // Functions commonly defined on Object + "toString", + "getClass", + "constructor", + "prototype", + + // Client-side JavaScript identifiers, which are needed for linkers + // that don't ensure GWT's window != $wnd, document != $doc, etc. + // Taken from the Rhino book, pg 715 + "Anchor", "Applet", "Attr", "Canvas", "CanvasGradient", "CanvasPattern", + "CanvasRenderingContext2D", "CDATASection", "CharacterData", "Comment", + "CSS2Properties", "CSSRule", "CSSStyleSheet", "Document", + "DocumentFragment", "DocumentType", "DOMException", "DOMImplementation", + "DOMParser", "Element", "Event", "ExternalInterface", "FlashPlayer", + "Form", "Frame", "History", "HTMLCollection", "HTMLDocument", + "HTMLElement", "IFrame", "Image", "Input", "JSObject", "KeyEvent", + "Link", "Location", "MimeType", "MouseEvent", "Navigator", "Node", + "NodeList", "Option", "Plugin", "ProcessingInstruction", "Range", + "RangeException", "Screen", "Select", "Table", "TableCell", "TableRow", + "TableSelection", "Text", "TextArea", "UIEvent", "Window", + "XMLHttpRequest", "XMLSerializer", "XPathException", "XPathResult", + "XSLTProcessor", + + /* + * These keywords trigger the loading of the java-plugin. For the + * next-generation plugin, this results in starting a new Java process. + */ + "java", "Packages", "netscape", "sun", "JavaObject", "JavaClass", + "JavaArray", "JavaMember", + + // GWT-defined identifiers + "$wnd", "$doc", "$moduleName", "$moduleBase", "$gwt_version", + "$sessionId", + + // Identifiers used by JsStackEmulator; later set to obfuscatable + "$stack", "$stackDepth", "$location", + + // TODO: prove why this is necessary or remove it + "call",}; + + static { + INSTANCE = new JsRootScope(); + } + + private final Map<String, JsName> names = new LinkedHashMap<String, JsName>(); + + private final JsName undefined; + + private JsRootScope() { super("Root"); - this.program = program; - ctorAddKnownGlobalSymbols(); + for (String ident : COMMON_BUILTINS) { + names.put(ident, new JsRootName(this, ident)); + } + undefined = names.get("undefined"); + assert undefined != null; } @Override - public JsProgram getProgram() { - return program; + public Iterator<JsName> getAllNames() { + return Collections.unmodifiableCollection(names.values()).iterator(); + } + + @Override + public List<JsScope> getChildren() { + return Lists.create(); + } + + @Override + public JsScope getParent() { + return null; + } + + public JsName getUndefined() { + return undefined; + } + + @Override + protected void addChild(JsScope child) { + // Don't record children. } @Override protected JsName doCreateName(String ident, String shortIdent) { - JsName name = super.doCreateName(ident, shortIdent); - name.setObfuscatable(false); - return name; + throw new UnsupportedOperationException( + "Cannot create new names in the root scope"); } - private void ctorAddKnownGlobalSymbols() { - // Section references are from Ecma-262 - // (http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf) - String[] commonBuiltins = new String[]{ - // 15.1.1 Value Properties of the Global Object - "NaN", - "Infinity", - "undefined", + @Override + protected JsName findExistingNameNoRecurse(String ident) { + return names.get(ident); + } - // 15.1.2 Function Properties of the Global Object - "eval", - "parseInt", - "parseFloat", - "isNan", - "isFinite", - - // 15.1.3 URI Handling Function Properties - "decodeURI", - "decodeURIComponent", - "encodeURI", - "encodeURIComponent", - - // 15.1.4 Constructor Properties of the Global Object - "Object", - "Function", - "Array", - "String", - "Boolean", - "Number", - "Date", - "RegExp", - "Error", - "EvalError", - "RangeError", - "ReferenceError", - "SyntaxError", - "TypeError", - "URIError", - - // 15.1.5 Other Properties of the Global Object - "Math", - - // 10.1.6 Activation Object - "arguments", - - // B.2 Additional Properties (non-normative) - "escape", - "unescape", - - // Window props (https://developer.mozilla.org/en/DOM/window) - "applicationCache", - "closed", - "Components", - "content", - "controllers", - "crypto", - "defaultStatus", - "dialogArguments", - "directories", - "document", - "frameElement", - "frames", - "fullScreen", - "globalStorage", - "history", - "innerHeight", - "innerWidth", - "length", - "location", - "locationbar", - "localStorage", - "menubar", - "mozInnerScreenX", - "mozInnerScreenY", - "mozScreenPixelsPerCssPixel", - "name", - "navigator", - "opener", - "outerHeight", - "outerWidth", - "pageXOffset", - "pageYOffset", - "parent", - "personalbar", - "pkcs11", - "returnValue", - "screen", - "scrollbars", - "scrollMaxX", - "scrollMaxY", - "self", - "sessionStorage", - "sidebar", - "status", - "statusbar", - "toolbar", - "top", - "window", - - // Window methods (https://developer.mozilla.org/en/DOM/window) - "alert", - "addEventListener", - "atob", - "back", - "blur", - "btoa", - "captureEvents", - "clearInterval", - "clearTimeout", - "close", - "confirm", - "disableExternalCapture", - "dispatchEvent", - "dump", - "enableExternalCapture", - "escape", - "find", - "focus", - "forward", - "GeckoActiveXObject", - "getAttention", - "getAttentionWithCycleCount", - "getComputedStyle", - "getSelection", - "home", - "maximize", - "minimize", - "moveBy", - "moveTo", - "open", - "openDialog", - "postMessage", - "print", - "prompt", - "QueryInterface", - "releaseEvents", - "removeEventListener", - "resizeBy", - "resizeTo", - "restore", - "routeEvent", - "scroll", - "scrollBy", - "scrollByLines", - "scrollByPages", - "scrollTo", - "setInterval", - "setResizeable", - "setTimeout", - "showModalDialog", - "sizeToContent", - "stop", - "uuescape", - "updateCommands", - "XPCNativeWrapper", - "XPCSafeJSOjbectWrapper", - - // Mozilla Window event handlers, same cite - "onabort", - "onbeforeunload", - "onchange", - "onclick", - "onclose", - "oncontextmenu", - "ondragdrop", - "onerror", - "onfocus", - "onhashchange", - "onkeydown", - "onkeypress", - "onkeyup", - "onload", - "onmousedown", - "onmousemove", - "onmouseout", - "onmouseover", - "onmouseup", - "onmozorientation", - "onpaint", - "onreset", - "onresize", - "onscroll", - "onselect", - "onsubmit", - "onunload", - - // Safari Web Content Guide - // http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/SafariWebContent.pdf - // WebKit Window member data, from WebKit DOM Reference - // (http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/WebKitDOMRef/DOMWindow_idl/Classes/DOMWindow/index.html) - // TODO(fredsa) Many, many more functions and member data to add - "ontouchcancel", - "ontouchend", - "ontouchmove", - "ontouchstart", - "ongesturestart", - "ongesturechange", - "ongestureend", - - // extra window methods - "uneval", - - // keywords https://developer.mozilla.org/en/New_in_JavaScript_1.7, - // https://developer.mozilla.org/en/New_in_JavaScript_1.8.1 - "getPrototypeOf", - "let", - - // "future reserved words" - "abstract", - "int", - "short", - "boolean", - "interface", - "static", - "byte", - "long", - "char", - "final", - "native", - "synchronized", - "float", - "package", - "throws", - "goto", - "private", - "transient", - "implements", - "protected", - "volatile", - "double", - "public", - - // IE methods - // (http://msdn.microsoft.com/en-us/library/ms535873(VS.85).aspx#) - "attachEvent", - "clientInformation", - "clipboardData", - "createPopup", - "dialogHeight", - "dialogLeft", - "dialogTop", - "dialogWidth", - "onafterprint", - "onbeforedeactivate", - "onbeforeprint", - "oncontrolselect", - "ondeactivate", - "onhelp", - "onresizeend", - - // Common browser-defined identifiers not defined in ECMAScript - "event", - "external", - "Debug", - "Enumerator", - "Global", - "Image", - "ActiveXObject", - "VBArray", - "Components", - - // Functions commonly defined on Object - "toString", - "getClass", - "constructor", - "prototype", - - // Client-side JavaScript identifiers, which are needed for linkers - // that don't ensure GWT's window != $wnd, document != $doc, etc. - // Taken from the Rhino book, pg 715 - "Anchor", "Applet", "Attr", "Canvas", "CanvasGradient", - "CanvasPattern", "CanvasRenderingContext2D", "CDATASection", - "CharacterData", "Comment", "CSS2Properties", "CSSRule", - "CSSStyleSheet", "Document", "DocumentFragment", "DocumentType", - "DOMException", "DOMImplementation", "DOMParser", "Element", "Event", - "ExternalInterface", "FlashPlayer", "Form", "Frame", "History", - "HTMLCollection", "HTMLDocument", "HTMLElement", "IFrame", "Image", - "Input", "JSObject", "KeyEvent", "Link", "Location", "MimeType", - "MouseEvent", "Navigator", "Node", "NodeList", "Option", "Plugin", - "ProcessingInstruction", "Range", "RangeException", "Screen", "Select", - "Table", "TableCell", "TableRow", "TableSelection", "Text", "TextArea", - "UIEvent", "Window", "XMLHttpRequest", "XMLSerializer", - "XPathException", "XPathResult", "XSLTProcessor", - - /* - * These keywords trigger the loading of the java-plugin. For the - * next-generation plugin, this results in starting a new Java process. - */ - "java", "Packages", "netscape", "sun", "JavaObject", "JavaClass", - "JavaArray", "JavaMember", - - // GWT-defined identifiers - "$wnd", "$doc", "$entry", "$moduleName", "$moduleBase", "$gwt_version", - "$sessionId", - - // Identifiers used by JsStackEmulator; later set to obfuscatable - "$stack", "$stackDepth", "$location", - - // TODO: prove why this is necessary or remove it - "call",}; - - for (int i = 0; i < commonBuiltins.length; i++) { - String ident = commonBuiltins[i]; - this.doCreateName(ident, ident); - } + private Object writeReplace() { + return new SerializedForm(); } }
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsScope.java b/dev/core/src/com/google/gwt/dev/js/ast/JsScope.java index 5dc5ed9..a1ff03c 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsScope.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsScope.java
@@ -17,14 +17,10 @@ import com.google.gwt.dev.js.JsKeywords; import com.google.gwt.dev.util.StringInterner; -import com.google.gwt.dev.util.collect.Lists; -import com.google.gwt.dev.util.collect.Maps; import java.io.Serializable; -import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Map; /** * A scope is a factory for creating and allocating @@ -51,7 +47,7 @@ * qualifier and could therefore never be confused with the global scope * hierarchy. */ -public class JsScope implements Serializable { +public abstract class JsScope implements Serializable { /** * Prevents the client from programmatically creating an illegal ident. @@ -63,27 +59,10 @@ return StringInterner.get().intern(ident); } - private List<JsScope> children = Collections.emptyList(); private final String description; - private Map<String, JsName> names = Collections.emptyMap(); - private final JsScope parent; - /** - * Create a scope with parent. - */ - public JsScope(JsScope parent, String description) { - assert (parent != null); - this.description = StringInterner.get().intern(description); - this.parent = parent; - parent.children = Lists.add(parent.children, this); - } - - /** - * Subclasses can be parentless. - */ protected JsScope(String description) { this.description = StringInterner.get().intern(description); - this.parent = null; } /** @@ -92,7 +71,7 @@ * * @param ident An identifier that is unique within this scope. */ - public JsName declareName(String ident) { + public final JsName declareName(String ident) { ident = maybeMangleKeyword(ident); JsName name = findExistingNameNoRecurse(ident); if (name != null) { @@ -110,7 +89,7 @@ * @throws IllegalArgumentException if ident already exists in this scope but * the requested short name does not match the existing short name. */ - public JsName declareName(String ident, String shortIdent) { + public final JsName declareName(String ident, String shortIdent) { ident = maybeMangleKeyword(ident); shortIdent = maybeMangleKeyword(shortIdent); JsName name = findExistingNameNoRecurse(ident); @@ -134,8 +113,8 @@ public final JsName findExistingName(String ident) { ident = maybeMangleKeyword(ident); JsName name = findExistingNameNoRecurse(ident); - if (name == null && parent != null) { - return parent.findExistingName(ident); + if (name == null && getParent() != null) { + return getParent().findExistingName(ident); } return name; } @@ -152,8 +131,8 @@ if (name != null && name.isObfuscatable()) { name = null; } - if (name == null && parent != null) { - return parent.findExistingUnobfuscatableName(ident); + if (name == null && getParent() != null) { + return getParent().findExistingUnobfuscatableName(ident); } return name; } @@ -161,52 +140,34 @@ /** * Returns an iterator for all the names defined by this scope. */ - public Iterator<JsName> getAllNames() { - return names.values().iterator(); - } + public abstract Iterator<JsName> getAllNames(); /** * Returns a list of this scope's child scopes. */ - public final List<JsScope> getChildren() { - return children; - } + public abstract List<JsScope> getChildren(); /** * Returns the parent scope of this scope, or <code>null</code> if this is the * root scope. */ - public final JsScope getParent() { - return parent; - } - - /** - * Returns the associated program. - */ - public JsProgram getProgram() { - assert (parent != null) : "Subclasses must override getProgram() if they do not set a parent"; - return parent.getProgram(); - } + public abstract JsScope getParent(); @Override public final String toString() { - if (parent != null) { - return description + "->" + parent; + if (getParent() != null) { + return description + "->" + getParent(); } else { return description; } } + protected abstract void addChild(JsScope child); + /** * Creates a new name in this scope. */ - protected JsName doCreateName(String ident, String shortIdent) { - ident = StringInterner.get().intern(ident); - shortIdent = StringInterner.get().intern(shortIdent); - JsName name = new JsName(this, ident, shortIdent); - names = Maps.putOrdered(names, ident, name); - return name; - } + protected abstract JsName doCreateName(String ident, String shortIdent); /** * Attempts to find the name object for the specified ident, searching in this @@ -214,8 +175,5 @@ * * @return <code>null</code> if the identifier has no associated name */ - protected JsName findExistingNameNoRecurse(String ident) { - return names.get(ident); - } - + protected abstract JsName findExistingNameNoRecurse(String ident); }
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsStringLiteral.java b/dev/core/src/com/google/gwt/dev/js/ast/JsStringLiteral.java index 6691d80..7eba50f 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsStringLiteral.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsStringLiteral.java
@@ -25,8 +25,7 @@ private final String value; - // These only get created by JsProgram so that they can be interned. - JsStringLiteral(SourceInfo sourceInfo, String value) { + public JsStringLiteral(SourceInfo sourceInfo, String value) { super(sourceInfo); this.value = StringInterner.get().intern(value); }
diff --git a/dev/core/src/com/google/gwt/dev/shell/Jsni.java b/dev/core/src/com/google/gwt/dev/shell/Jsni.java index a5a2d45..5c2b519 100644 --- a/dev/core/src/com/google/gwt/dev/shell/Jsni.java +++ b/dev/core/src/com/google/gwt/dev/shell/Jsni.java
@@ -15,7 +15,6 @@ */ package com.google.gwt.dev.shell; -import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.dev.javac.JsniMethod; import com.google.gwt.dev.jjs.SourceInfo; import com.google.gwt.dev.js.JsSourceGenerationVisitor; @@ -25,7 +24,8 @@ import com.google.gwt.dev.js.ast.JsInvocation; import com.google.gwt.dev.js.ast.JsNameRef; import com.google.gwt.dev.js.ast.JsNode; -import com.google.gwt.dev.js.ast.JsProgram; +import com.google.gwt.dev.js.ast.JsNullLiteral; +import com.google.gwt.dev.js.ast.JsNumberLiteral; import com.google.gwt.dev.util.DefaultTextOutput; import com.google.gwt.dev.util.TextOutput; @@ -85,14 +85,11 @@ JsSourceGenerationVisitor { private final DispatchIdOracle dispatchInfo; private final TextOutput out; - private final JsProgram program; - public JsSourceGenWithJsniIdentFixup(TextOutput out, DispatchIdOracle ccl, - JsProgram program) { + public JsSourceGenWithJsniIdentFixup(TextOutput out, DispatchIdOracle ccl) { super(out); this.dispatchInfo = ccl; this.out = out; - this.program = program; } /** @@ -149,11 +146,11 @@ List<JsExpression> arguments = rewritten.getArguments(); if (q == null) { - q = program.getNullLiteral(); + q = JsNullLiteral.INSTANCE; } arguments.add(q); - arguments.add(program.getNumberLiteral(dispId)); - arguments.add(program.getNumberLiteral(paramCount)); + arguments.add(new JsNumberLiteral(newSourceInfo, dispId)); + arguments.add(new JsNumberLiteral(newSourceInfo, paramCount)); accept(rewritten); return false; @@ -210,17 +207,18 @@ JsInvocation inner = new JsInvocation(newSourceInfo); inner.setQualifier(new JsNameRef(newSourceInfo, "__gwt_makeJavaInvoke")); - inner.getArguments().add(program.getNumberLiteral(paramCount)); + inner.getArguments().add( + new JsNumberLiteral(newSourceInfo, paramCount)); JsInvocation outer = new JsInvocation(newSourceInfo); outer.setQualifier(inner); JsExpression q = ref.getQualifier(); if (q == null) { - q = program.getNullLiteral(); + q = JsNullLiteral.INSTANCE; } List<JsExpression> arguments = outer.getArguments(); arguments.add(q); - arguments.add(program.getNumberLiteral(dispId)); + arguments.add(new JsNumberLiteral(newSourceInfo, dispId)); arguments.addAll(x.getArguments()); accept(outer); @@ -240,14 +238,13 @@ * * @param logger a TreeLogger */ - public static String getJavaScriptForHostedMode(TreeLogger logger, + public static String getJavaScriptForHostedMode( DispatchIdOracle dispatchInfo, JsniMethod jsniMethod) { JsFunction func = jsniMethod.function(); if (func == null) { return null; } - return generateJavaScriptForHostedMode(dispatchInfo, jsniMethod.program(), - func.getBody()); + return generateJavaScriptForHostedMode(dispatchInfo, func.getBody()); } /** @@ -255,10 +252,10 @@ * JSNI idents have been replaced with legal JavaScript for hosted mode. */ private static String generateJavaScriptForHostedMode( - DispatchIdOracle dispatchInfo, JsProgram program, JsNode node) { + DispatchIdOracle dispatchInfo, JsNode node) { DefaultTextOutput out = new DefaultTextOutput(false); JsSourceGenWithJsniIdentFixup vi = new JsSourceGenWithJsniIdentFixup(out, - dispatchInfo, program); + dispatchInfo); vi.accept(node); return out.toString(); }
diff --git a/dev/core/src/com/google/gwt/dev/shell/ModuleSpaceOOPHM.java b/dev/core/src/com/google/gwt/dev/shell/ModuleSpaceOOPHM.java index 97b2f05..8ef7931 100644 --- a/dev/core/src/com/google/gwt/dev/shell/ModuleSpaceOOPHM.java +++ b/dev/core/src/com/google/gwt/dev/shell/ModuleSpaceOOPHM.java
@@ -49,7 +49,7 @@ if (jsniMethod.isScriptOnly()) { continue; } - String body = Jsni.getJavaScriptForHostedMode(logger, dispatchIdOracle, + String body = Jsni.getJavaScriptForHostedMode(dispatchIdOracle, jsniMethod); if (body == null) { // The error has been logged; just ignore it for now.
diff --git a/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java b/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java index 133e356..6a015b0 100644 --- a/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java +++ b/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java
@@ -152,7 +152,7 @@ code.append(" private final String name;\n"); code.append(" private final int ordinal;\n"); code.append(" public final String name() { return name; }\n"); - code.append(" public final int ordinal() { return ordinal; }\n"); + code.append(" public final int ordinal() { return ordinal; }\n"); code.append("}\n"); return code; } @@ -231,7 +231,7 @@ JavaToJavaScriptCompiler.checkForErrors(logger, goldenCuds, true); - CorrelationFactory correlator = new DummyCorrelationFactory(); + CorrelationFactory correlator = DummyCorrelationFactory.INSTANCE; JProgram jprogram = new JProgram(correlator); JsProgram jsProgram = new JsProgram(correlator);
diff --git a/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorAccuracyTest.java b/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorAccuracyTest.java index 590ffe4..5a99ddd 100644 --- a/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorAccuracyTest.java +++ b/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorAccuracyTest.java
@@ -18,6 +18,7 @@ import com.google.gwt.dev.jjs.SourceOrigin; import com.google.gwt.dev.js.ast.JsProgram; import com.google.gwt.dev.js.ast.JsStatement; +import com.google.gwt.dev.js.ast.JsStringLiteral; import com.google.gwt.dev.js.ast.JsVisitor; import com.google.gwt.dev.util.DefaultTextOutput; import com.google.gwt.dev.util.TextOutput; @@ -192,8 +193,7 @@ } private void doTestEscapes(String value, String expected) { - String actual = new JsProgram().getStringLiteral(SourceOrigin.UNKNOWN, - value).toString(); + String actual = new JsStringLiteral(SourceOrigin.UNKNOWN, value).toString(); assertEquals(expected, actual); }