Rolling back to the last known good state: r5776
svn merge -rHEAD:5776 https://google-web-toolkit.googlecode.com/svn/trunk
Patch by: amitmanjhi, rjrjr
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5794 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/build-tools/ant-gwt/build.xml b/build-tools/ant-gwt/build.xml
index b08e085..81b02d6 100644
--- a/build-tools/ant-gwt/build.xml
+++ b/build-tools/ant-gwt/build.xml
@@ -3,10 +3,6 @@
<property name="project.tail" value="build-tools/ant-gwt" />
<import file="${gwt.root}/common.ant.xml" />
- <fileset id="default.tests" dir="${javac.junit.out}">
- <include name="**/*Test.class" />
- </fileset>
-
<target name="compile" description="Compiles this project">
<mkdir dir="${javac.out}" />
<gwt.javac>
@@ -16,7 +12,7 @@
</gwt.javac>
</target>
- <target name="compile.tests" depends="build, compile.emma" description="Compiles the test code for this project">
+ <target name="compile.tests" depends="build" description="Compiles the test code for this project">
<mkdir dir="${javac.junit.out}" />
<gwt.javac srcdir="test" destdir="${javac.junit.out}">
<classpath>
@@ -37,7 +33,32 @@
</target>
<target name="test" depends="build, compile.tests" description="Run unit tests for this project.">
- <gwt.junit test.out="${junit.out}" test.cases="default.tests" />
+ <!-- TODO: refactor gwt.junit so it can be reused here -->
+ <taskdef name="junit" classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask">
+ <classpath>
+ <pathelement location="${gwt.tools.lib}/junit/junit-3.8.1.jar" />
+ <pathelement location="${gwt.tools.antlib}/ant-junit-1.6.5.jar" />
+ </classpath>
+ </taskdef>
+
+ <echo message="Writing test results to ${junit.out}/reports for ${test.cases}" />
+ <mkdir dir="${junit.out}/reports" />
+
+ <echo message="${javac.out} ${javac.junit.out}" />
+ <junit dir="${junit.out}" fork="yes" printsummary="yes" haltonfailure="true">
+ <classpath>
+ <pathelement location="${javac.junit.out}" />
+ <pathelement location="${javac.out}" />
+ <pathelement location="${gwt.tools.lib}/junit/junit-3.8.1.jar" />
+ </classpath>
+
+ <formatter type="plain" />
+ <formatter type="xml" />
+
+ <batchtest todir="${junit.out}/reports">
+ <fileset dir="${javac.junit.out}" includes="**/*Test.class" />
+ </batchtest>
+ </junit>
</target>
<target name="checkstyle" description="Static analysis of source">
diff --git a/build.xml b/build.xml
index 858db11..8fbc6c5 100755
--- a/build.xml
+++ b/build.xml
@@ -5,7 +5,6 @@
<!-- "build" is the default when subprojects are directly targetted -->
<property name="target" value="build" />
- <property name="emma.merged.out" value="${project.build}/emma-coverage" />
<!--
Convenience for the lateral calls we make. Use gwt.ant to
@@ -128,39 +127,6 @@
<call-subproject subproject="tools" subtarget="test" />
</target>
- <path id="emma.classpath.src">
- <pathelement location="${gwt.root}/user/src" />
- <pathelement location="${gwt.root}/dev/**/src/com/google" />
- <pathelement location="${gwt.root}/build-tools/**/src/com/google" />
- <pathelement location="${gwt.root}/tools/**/src/com/google" />
- </path>
-
- <target name="emma.merge" description="Merges coverage data for all projects" if="emma.enabled">
- <delete dir="${emma.merged.out}" />
- <mkdir dir="${emma.merged.out}" />
- <emma>
- <merge outfile="${emma.merged.out}/merged.emma" >
- <fileset dir="${project.build}" >
- <include name="**/*.emma" />
- <exclude name="**/merged.emma" />
- </fileset>
- </merge>
- </emma>
- <emma enabled="${emma.enabled}">
- <report sourcepath="${emma.classpath.src}">
- <fileset dir="${project.build}">
- <patternset>
- <include name="**/metadata.emma"/>
- </patternset>
- </fileset>
- <fileset file="${emma.merged.out}/merged.emma" />
- <txt outfile="${emma.merged.out}/coverage.txt" />
- <html outfile="${emma.merged.out}/coverage.html" />
- <xml outfile="${emma.merged.out}/coverage.xml" />
- </report>
- </emma>
- </target>
-
<target name="clean" description="[action] Cleans the entire GWT build">
<delete dir="${gwt.build}" />
</target>
diff --git a/common.ant.xml b/common.ant.xml
index 41bac4d..37cfcce 100755
--- a/common.ant.xml
+++ b/common.ant.xml
@@ -49,7 +49,6 @@
<property name="project.jni" location="${gwt.build}/${project.tail}" />
<property name="javac.out" location="${project.build}/bin" />
<property name="javac.junit.out" location="${project.build}/bin-test" />
- <property name="javac.emma.out" location="${project.build}/bin-emma" />
<property name="javac.debug" value="true" />
<property name="javac.debuglevel" value="lines,vars,source" />
<property name="javac.encoding" value="utf-8" />
@@ -57,8 +56,6 @@
<property name="javac.target" value="1.5" />
<property name="javac.nowarn" value="true" />
<property name="junit.out" location="${project.build}/test" />
- <property name="emma.dir" value="${gwt.tools.redist}/emma" />
- <property name="emma.filter.exclude" value="" />
<!-- Sanity check -->
<available file="${gwt.tools}" type="dir" property="gwt.tools.exists" />
@@ -122,14 +119,6 @@
</not>
</condition>
- <!-- Shared class paths -->
- <path id="project.classpath.class">
- <pathelement location="${javac.out}" />
- </path>
- <path id="project.classpath.src">
- <pathelement location="${gwt.root}/${project.tail}/src" />
- </path>
-
<!-- Pulls in tasks defined in ant-contrib, i.e. foreach -->
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
@@ -144,7 +133,6 @@
<propertyref name="gwt.version" />
<propertyref name="gwt.junit.port" />
<propertyref name="gwt.remote.browsers" />
- <propertyref name="emma.enabled" />
</propertyset>
</ant>
</presetdef>
@@ -175,7 +163,6 @@
<attribute name="test.args" default="" />
<attribute name="test.out" default="" />
<attribute name="test.reports" default="@{test.out}/reports" />
- <attribute name="test.emma.coverage" default="@{test.out}/emma-coverage" />
<attribute name="test.cases" default="" />
<element name="extraclasspaths" optional="true" />
<sequential>
@@ -190,28 +177,20 @@
<echo message="Writing test results to @{test.reports} for @{test.cases}" />
<mkdir dir="@{test.reports}" />
- <antcall target="-create.emma.coverage">
- <param name="test.emma.coverage" value="@{test.emma.coverage}"/>
- </antcall>
-
<echo message="${javac.out} ${javac.junit.out}" />
<junit dir="@{test.out}" fork="yes" printsummary="yes"
failureproperty="junit.failure" tempdir="@{test.out}" >
<jvmarg line="${junit.platform.args}" />
<jvmarg line="-Xmx768m" />
- <jvmarg value="-Demma.coverage.out.file=@{test.emma.coverage}/coverage.emma" />
- <jvmarg value="-Demma.coverage.out.merge=true" />
<sysproperty key="gwt.args" value="${junit.notheadless.arg} @{test.args}" />
<sysproperty key="java.awt.headless" value="${junit.headless}" />
<sysproperty key="gwt.devjar" value="${gwt.dev.staging.jar}" />
<classpath>
- <path refid="project.classpath.src" />
+ <pathelement location="${gwt.root}/${project.tail}/src" />
<pathelement location="${gwt.root}/${project.tail}/super" />
<pathelement location="${gwt.root}/${project.tail}/test" />
<pathelement location="${javac.junit.out}" />
- <pathelement location="${javac.emma.out}" />
- <path refid="project.classpath.class" />
- <path refid="emma.lib" />
+ <pathelement location="${javac.out}" />
<pathelement location="${gwt.dev.staging.jar}" />
<pathelement location="${gwt.tools.lib}/junit/junit-3.8.1.jar" />
<pathelement location="${gwt.tools.lib}/selenium/selenium-java-client-driver.jar" />
@@ -227,19 +206,6 @@
<fileset refid="@{test.cases}" />
</batchtest>
</junit>
-
- <emma enabled="${emma.enabled}">
- <report sourcepath="${project.classpath.src}">
- <fileset file="${javac.emma.out}/metadata.emma" />
- <fileset dir="@{test.emma.coverage}">
- <include name="*.emma" />
- </fileset>
- <txt outfile="@{test.emma.coverage}/coverage.txt" />
- <html outfile="@{test.emma.coverage}/coverage.html" />
- <xml outfile="@{test.emma.coverage}/coverage.xml" />
- </report>
- </emma>
-
<fail message="One or more junit tests failed" if="junit.failure" />
</sequential>
</macrodef>
@@ -337,43 +303,6 @@
</sequential>
</macrodef>
- <!-- Targets for emma support. To run tests with emma enabled, use
- ant emma <test-target>. -->
- <path id="emma.lib">
- <pathelement location="${emma.dir}/emma-2.0.5312-patched.jar" />
- <pathelement location="${emma.dir}/emma_ant-2.0.5312.jar" />
- </path>
-
- <taskdef resource="emma_ant.properties" classpathref="emma.lib" />
-
- <target name="emma" description="Enables on EMMA instrumentation/reporting" >
- <property name="emma.enabled" value="true" />
- </target>
-
- <target name="compile.emma" description="Instruments emma classes" unless="emma.compiled">
- <delete dir="${javac.emma.out}" />
- <property name="emma.compiled" value="true" />
- <antcall target="-compile.emma.if.enabled" />
- </target>
-
- <target name="-compile.emma.if.enabled" description="Instruments emma classes" if="emma.enabled">
- <mkdir dir="${javac.emma.out}" />
- <path id="emma.classpath">
- <pathelement location="${javac.out}" />
- </path>
- <emma enabled="${emma.enabled}" >
- <instr instrpathref="emma.classpath" destdir="${javac.emma.out}" metadatafile="${javac.emma.out}/metadata.emma" merge="false">
- <filter includes="com.google.*" />
- <filter excludes="${emma.filter.exclude}" />
- </instr>
- </emma>
- </target>
-
- <target name="-create.emma.coverage" description="Create the emma coverage directory" if="emma.enabled">
- <delete dir="${test.emma.coverage}" />
- <mkdir dir="${test.emma.coverage}" />
- </target>
-
<!-- Default implementations of the required targets; projects should
override the ones that matter -->
<target name="all" depends="verify" />
diff --git a/dev/core/build.xml b/dev/core/build.xml
index 11ee628..e868ed4 100755
--- a/dev/core/build.xml
+++ b/dev/core/build.xml
@@ -9,7 +9,7 @@
<include name="**/com/google/**/*Test.class" />
</fileset>
- <target name="compile.tests" depends="build, compile.emma" description="Compiles the test code for this project">
+ <target name="compile.tests" depends="build" description="Compiles the test code for this project">
<mkdir dir="${javac.junit.out}" />
<gwt.javac srcdir="test" destdir="${javac.junit.out}">
<classpath>
@@ -166,14 +166,38 @@
</target>
<target name="test" depends="build, compile.tests" description="Run unit tests for this project.">
- <gwt.junit test.out="${junit.out}" test.cases="default.tests" >
- <extraclasspaths>
+ <!-- TODO: refactor gwt.junit so it can be reused here -->
+ <taskdef name="junit" classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask">
+ <classpath>
+ <pathelement location="${gwt.tools.lib}/junit/junit-3.8.1.jar" />
+ <pathelement location="${gwt.tools.antlib}/ant-junit-1.6.5.jar" />
+ </classpath>
+ </taskdef>
+
+ <echo message="Writing test results to ${junit.out}/reports for ${test.cases}" />
+ <mkdir dir="${junit.out}/reports" />
+
+ <echo message="${javac.out} ${javac.junit.out}" />
+ <junit dir="${junit.out}" fork="yes" printsummary="yes" haltonfailure="true">
+ <classpath>
+ <pathelement location="test" />
+ <pathelement location="${javac.junit.out}" />
+ <pathelement location="${javac.out}" />
<pathelement location="${alldeps.jar}" />
+ <pathelement location="${gwt.tools.lib}/junit/junit-3.8.1.jar" />
<!-- Pull in gwt-dev and gwt-user sources for .gwt.xml files -->
<pathelement location="${gwt.root}/user/src/" />
<pathelement location="${gwt.root}/user/super/" />
- </extraclasspaths>
- </gwt.junit>
+ <pathelement location="${gwt.root}/dev/core/super" />
+ </classpath>
+
+ <formatter type="plain" />
+ <formatter type="xml" />
+
+ <batchtest todir="${junit.out}/reports">
+ <fileset refid="default.tests" />
+ </batchtest>
+ </junit>
</target>
<target name="clean" description="Cleans this project's intermediate and output files">
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 03ca1b4..d99c393 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -92,7 +92,6 @@
import com.google.gwt.dev.js.JsPrettyNamer;
import com.google.gwt.dev.js.JsReportGenerationVisitor;
import com.google.gwt.dev.js.JsSourceGenerationVisitor;
-import com.google.gwt.dev.js.JsStackEmulator;
import com.google.gwt.dev.js.JsStaticEval;
import com.google.gwt.dev.js.JsStringInterner;
import com.google.gwt.dev.js.JsSymbolResolver;
@@ -141,7 +140,7 @@
private final byte[] serializedSymbolMap;
private final StatementRanges[] statementRanges;
private final int permutationId;
-
+
public PermutationResultImpl(String[] js, SymbolData[] symbolMap,
StatementRanges[] statementRanges, int permutationId) {
byte[][] bytes = new byte[js.length][];
@@ -168,7 +167,7 @@
public byte[][] getJs() {
return js;
}
-
+
public int getPermutationId() {
return permutationId;
}
@@ -271,18 +270,6 @@
} while (didChange);
}
- /*
- * Creates new variables, must run before namer
- *
- * TODO(bobv): This is a temporary hack to conditionally map in this pass.
- * Once deferred-binding properties can specify a subset of the
- * permutation matrix, revisit this if statement.
- */
- if (jprogram.getDeclaredTypes().contains(
- jprogram.getFromTypeMap("com.google.gwt.core.client.impl.StackTraceCreator.CollectorEmulated"))) {
- JsStackEmulator.exec(jsProgram, propertyOracles);
- }
-
// (10) Obfuscate
final Map<JsName, String> stringLiteralMap;
switch (options.getOutput()) {
@@ -323,6 +310,7 @@
// Work around an IE7 bug,
// http://code.google.com/p/google-web-toolkit/issues/detail?id=1440
JsIEBlockSizeVisitor.exec(jsProgram);
+
JsBreakUpLargeVarStatements.exec(jsProgram, propertyOracles);
// (12) Generate the final output text.
@@ -352,8 +340,7 @@
makeSymbolMap(symbolTable), ranges, permutationId);
toReturn.getArtifacts().add(
- makeSoycArtifact(logger, permutationId, jprogram, js, sourceInfoMaps,
- dependencies));
+ makeSoycArtifact(logger, permutationId, jprogram, js, sourceInfoMaps, dependencies));
System.out.println("Permutation took "
+ (System.currentTimeMillis() - permStart) + " ms");
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 f055d8d..38e7411 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
@@ -35,7 +35,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
@@ -694,10 +693,6 @@
return method;
}
- public Collection<JMethod> getIndexedMethods() {
- return Collections.unmodifiableCollection(indexedMethods.values());
- }
-
public JDeclaredType getIndexedType(String string) {
JDeclaredType type = indexedTypes.get(string);
if (type == null) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
index 7e544cf..36f6156 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
@@ -18,8 +18,8 @@
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JBlock;
-import com.google.gwt.dev.jjs.ast.JDeclarationStatement;
import com.google.gwt.dev.jjs.ast.JExpression;
+import com.google.gwt.dev.jjs.ast.JExpressionStatement;
import com.google.gwt.dev.jjs.ast.JIfStatement;
import com.google.gwt.dev.jjs.ast.JInstanceOf;
import com.google.gwt.dev.jjs.ast.JLocal;
@@ -63,17 +63,17 @@
}
SourceInfo catchInfo = x.getCatchBlocks().get(0).getSourceInfo();
- JLocal exVar = popTempLocal();
- JBlock newCatchBlock = new JBlock(catchInfo);
- {
- // $e = Exceptions.caught($e)
- JMethod caughtMethod = program.getIndexedMethod("Exceptions.caught");
- JMethodCall call = new JMethodCall(catchInfo, null, caughtMethod);
- call.addArg(new JLocalRef(catchInfo, exVar));
- newCatchBlock.addStmt(program.createAssignmentStmt(catchInfo,
- new JLocalRef(catchInfo, exVar), call));
- }
+ JLocal exObj = popTempLocal();
+ JLocalRef exRef = new JLocalRef(catchInfo, exObj);
+ JBlock newCatchBlock = new JBlock(catchInfo);
+ // $e = Exceptions.caught($e)
+ JMethod caughtMethod = program.getIndexedMethod("Exceptions.caught");
+ JMethodCall call = new JMethodCall(catchInfo, null, caughtMethod);
+ call.addArg(exRef);
+ JExpressionStatement asg = program.createAssignmentStmt(catchInfo, exRef,
+ call);
+ newCatchBlock.addStmt(asg);
/*
* Build up a series of if, else if statements to test the type of the
@@ -82,21 +82,18 @@
* Go backwards so we can nest the else statements in the correct order!
*/
// rethrow the current exception if no one caught it
- JStatement cur = new JThrowStatement(catchInfo, new JLocalRef(catchInfo,
- exVar));
+ JStatement cur = new JThrowStatement(catchInfo, exRef);
for (int i = x.getCatchBlocks().size() - 1; i >= 0; --i) {
JBlock block = x.getCatchBlocks().get(i);
JLocalRef arg = x.getCatchArgs().get(i);
catchInfo = block.getSourceInfo();
JReferenceType argType = (JReferenceType) arg.getType();
- // if ($e instanceof ArgType) { var userVar = $e; <user code> }
- JExpression ifTest = new JInstanceOf(catchInfo, argType, new JLocalRef(
- catchInfo, exVar));
- JDeclarationStatement declaration = new JDeclarationStatement(
- catchInfo, arg, new JLocalRef(catchInfo, exVar));
+ // if ($e instanceof ArgType) { userVar = $e; <user code> }
+ JExpression ifTest = new JInstanceOf(catchInfo, argType, exRef);
+ asg = program.createAssignmentStmt(catchInfo, arg, exRef);
if (!block.getStatements().isEmpty()) {
// Only bother adding the assignment if the block is non-empty
- block.addStmt(0, declaration);
+ block.addStmt(0, asg);
}
// nest the previous as an else for me
cur = new JIfStatement(catchInfo, ifTest, block, cur);
@@ -104,7 +101,7 @@
newCatchBlock.addStmt(cur);
x.getCatchArgs().clear();
- x.getCatchArgs().add(new JLocalRef(newCatchBlock.getSourceInfo(), exVar));
+ x.getCatchArgs().add(exRef);
x.getCatchBlocks().clear();
x.getCatchBlocks().add(newCatchBlock);
}
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 d66f376..b8f03dc 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
@@ -133,7 +133,6 @@
import com.google.gwt.dev.js.ast.JsVars;
import com.google.gwt.dev.js.ast.JsWhile;
import com.google.gwt.dev.js.ast.JsVars.JsVar;
-import com.google.gwt.dev.util.collect.Maps;
import java.util.ArrayList;
import java.util.Arrays;
@@ -361,11 +360,6 @@
jsFunction.getSourceInfo().addCorrelation(
program.getCorrelator().by(globalName));
push(jsFunction.getScope());
-
- if (program.getIndexedMethods().contains(x)) {
- indexedFunctions = Maps.put(indexedFunctions,
- x.getEnclosingType().getShortName() + "." + x.getName(), jsFunction);
- }
return true;
}
@@ -1891,8 +1885,6 @@
*/
private final JsScope interfaceScope;
- private Map<String, JsFunction> indexedFunctions = Maps.create();
-
private final JsProgram jsProgram;
/**
@@ -2122,8 +2114,6 @@
}
}
- jsProgram.setIndexedFunctions(indexedFunctions);
-
// TODO(spoon): Instead of gathering the information here, get it via
// SourceInfo
return new JavaToJavaScriptMap() {
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 d8b9d1b..aa2826c 100644
--- a/dev/core/src/com/google/gwt/dev/js/JsParser.java
+++ b/dev/core/src/com/google/gwt/dev/js/JsParser.java
@@ -29,7 +29,6 @@
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.JsExprStmt;
import com.google.gwt.dev.js.ast.JsExpression;
import com.google.gwt.dev.js.ast.JsFor;
import com.google.gwt.dev.js.ast.JsForIn;
@@ -151,12 +150,8 @@
private SourceInfo makeSourceInfo(Node node) {
SourceInfo parent = sourceInfoStack.peek();
- int lineno = node.getLineno();
- if (lineno == -1) {
- // Rhino only reports line numbers for statement nodes, not expressions
- return parent;
- }
- SourceInfo toReturn = program.createSourceInfo(lineno, parent.getFileName());
+ SourceInfo toReturn = program.createSourceInfo(node.getLineno(),
+ parent.getFileName());
toReturn.copyMissingCorrelationsFrom(parent);
return toReturn;
}
@@ -178,7 +173,7 @@
return null;
case TokenStream.EXPRSTMT:
- return mapExprStmt(node);
+ return mapExpression(node.getFirstChild()).makeStmt();
case TokenStream.REGEXP:
return mapRegExp(node);
@@ -351,8 +346,6 @@
*/
private JsNameRef mapAsPropertyNameRef(Node nameRefNode)
throws JsParserException {
- // Javac 1.6.0_01 doesn't like the cast below if this is parameterized
- @SuppressWarnings("unchecked")
JsNode unknown = map(nameRefNode);
// This is weird, but for "a.b", the rhino AST calls "b" a string literal.
// However, since we know it's for a PROPGET, we can unstringliteralize it.
@@ -423,11 +416,8 @@
}
private JsBlock mapBlock(Node nodeStmts) throws JsParserException {
- SourceInfo info = makeSourceInfo(nodeStmts);
- JsBlock block = new JsBlock(info);
- pushSourceInfo(info);
+ JsBlock block = new JsBlock(makeSourceInfo(nodeStmts));
mapStatements(block.getStatements(), nodeStmts);
- popSourceInfo();
return block;
}
@@ -523,9 +513,6 @@
fromTestExpr = ifNode.getFirstChild().getNext();
}
- SourceInfo info = makeSourceInfo(ifNode);
- pushSourceInfo(info);
-
// Map the test expression.
//
JsExpression toTestExpr = mapExpression(fromTestExpr);
@@ -534,14 +521,12 @@
//
JsStatement toBody = mapStatement(fromBody);
- popSourceInfo();
-
// Create and attach the "while" or "do" statement we're mapping to.
//
if (isWhile) {
- return new JsWhile(info, toTestExpr, toBody);
+ return new JsWhile(makeSourceInfo(ifNode), toTestExpr, toBody);
} else {
- return new JsDoWhile(info, toTestExpr, toBody);
+ return new JsDoWhile(makeSourceInfo(ifNode), toTestExpr, toBody);
}
}
@@ -578,8 +563,6 @@
}
private JsExpression mapExpression(Node exprNode) throws JsParserException {
- // Javac 1.6.0_01 doesn't like the cast below if this is parameterized
- @SuppressWarnings("unchecked")
JsNode unknown = map(exprNode);
if (unknown instanceof JsExpression) {
return (JsExpression) unknown;
@@ -588,13 +571,6 @@
}
}
- private JsExprStmt mapExprStmt(Node node) throws JsParserException {
- pushSourceInfo(makeSourceInfo(node));
- JsExpression expr = mapExpression(node.getFirstChild());
- popSourceInfo();
- return expr.makeStmt();
- }
-
private JsStatement mapForStatement(Node forNode) throws JsParserException {
Node fromInit = forNode.getFirstChild();
Node fromTest = fromInit.getNext();
@@ -647,8 +623,7 @@
JsFor toFor = new JsFor(makeSourceInfo(forNode));
// The first item is either an expression or a JsVars.
- // Javac 1.6.0_01 doesn't like the cast below if this is parameterized
- @SuppressWarnings("unchecked")
+ //
JsNode initThingy = map(fromInit);
if (initThingy != null) {
if (initThingy instanceof JsVars) {
@@ -864,8 +839,6 @@
private JsExpression mapOptionalExpression(Node exprNode)
throws JsParserException {
- // Javac 1.6.0_01 doesn't like the cast below if this is parameterized
- @SuppressWarnings("unchecked")
JsNode unknown = map(exprNode);
if (unknown != null) {
if (unknown instanceof JsExpression) {
@@ -955,16 +928,13 @@
}
private JsReturn mapReturn(Node returnNode) throws JsParserException {
- SourceInfo info = makeSourceInfo(returnNode);
- JsReturn toReturn = new JsReturn(info);
- pushSourceInfo(info);
+ JsReturn toReturn = new JsReturn(makeSourceInfo(returnNode));
Node from = returnNode.getFirstChild();
if (from != null) {
JsExpression to = mapExpression(from);
toReturn.setExpr(to);
}
- popSourceInfo();
return toReturn;
}
@@ -1014,8 +984,6 @@
}
private JsStatement mapStatement(Node nodeStmt) throws JsParserException {
- // Javac 1.6.0_01 doesn't like the cast below if this is parameterized
- @SuppressWarnings("unchecked")
JsNode unknown = map(nodeStmt);
if (unknown != null) {
if (unknown instanceof JsStatement) {
@@ -1055,9 +1023,7 @@
}
private JsSwitch mapSwitchStatement(Node switchNode) throws JsParserException {
- SourceInfo info = makeSourceInfo(switchNode);
- JsSwitch toSwitch = new JsSwitch(info);
- pushSourceInfo(info);
+ JsSwitch toSwitch = new JsSwitch(makeSourceInfo(switchNode));
// The switch expression.
//
@@ -1103,20 +1069,15 @@
fromMember = fromMember.getNext();
}
- popSourceInfo();
return toSwitch;
}
private JsThrow mapThrowStatement(Node throwNode) throws JsParserException {
- SourceInfo info = makeSourceInfo(throwNode);
- pushSourceInfo(info);
-
// Create, map, and attach.
//
Node fromExpr = throwNode.getFirstChild();
- JsThrow toThrow = new JsThrow(info, mapExpression(fromExpr));
-
- popSourceInfo();
+ JsThrow toThrow = new JsThrow(makeSourceInfo(throwNode),
+ mapExpression(fromExpr));
return toThrow;
}
@@ -1210,9 +1171,7 @@
}
private JsVars mapVar(Node varNode) throws JsParserException {
- SourceInfo info = makeSourceInfo(varNode);
- pushSourceInfo(info);
- JsVars toVars = new JsVars(info);
+ JsVars toVars = new JsVars(makeSourceInfo(varNode));
Node fromVar = varNode.getFirstChild();
while (fromVar != null) {
// Use a conservative name allocation strategy that allocates all names
@@ -1233,7 +1192,6 @@
fromVar = fromVar.getNext();
}
- popSourceInfo();
return toVars;
}
@@ -1253,24 +1211,8 @@
sourceInfoStack.pop();
}
- private void popSourceInfo() {
- sourceInfoStack.pop();
- }
-
private void pushScope(JsScope scope, SourceInfo sourceInfo) {
scopeStack.push(scope);
sourceInfoStack.push(sourceInfo);
}
-
- /**
- * This should be called when processing any Rhino statement Node that has
- * line number data so that enclosed expressions will have a useful source
- * location.
- *
- * @see Node#hasLineno
- */
- private void pushSourceInfo(SourceInfo sourceInfo) {
- assert sourceInfo.getStartLine() >= 0 : "Bad SourceInfo line number";
- sourceInfoStack.push(sourceInfo);
- }
}
diff --git a/dev/core/src/com/google/gwt/dev/js/JsStackEmulator.java b/dev/core/src/com/google/gwt/dev/js/JsStackEmulator.java
deleted file mode 100644
index 5451e3a..0000000
--- a/dev/core/src/com/google/gwt/dev/js/JsStackEmulator.java
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * Copyright 2009 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;
-
-import com.google.gwt.core.ext.BadPropertyValueException;
-import com.google.gwt.core.ext.PropertyOracle;
-import com.google.gwt.dev.jjs.HasSourceInfo;
-import com.google.gwt.dev.jjs.SourceInfo;
-import com.google.gwt.dev.js.ast.JsArrayAccess;
-import com.google.gwt.dev.js.ast.JsArrayLiteral;
-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.JsCatch;
-import com.google.gwt.dev.js.ast.JsContext;
-import com.google.gwt.dev.js.ast.JsExprStmt;
-import com.google.gwt.dev.js.ast.JsExpression;
-import com.google.gwt.dev.js.ast.JsFor;
-import com.google.gwt.dev.js.ast.JsFunction;
-import com.google.gwt.dev.js.ast.JsInvocation;
-import com.google.gwt.dev.js.ast.JsModVisitor;
-import com.google.gwt.dev.js.ast.JsName;
-import com.google.gwt.dev.js.ast.JsNameRef;
-import com.google.gwt.dev.js.ast.JsNew;
-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.JsStatement;
-import com.google.gwt.dev.js.ast.JsStringLiteral;
-import com.google.gwt.dev.js.ast.JsThrow;
-import com.google.gwt.dev.js.ast.JsTry;
-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.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;
-
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Emulates the JS stack in order to provide useful stack traces on browers that
- * do not provide useful stack information.
- *
- * @see com.google.gwt.core.client.impl.StackTraceCreator
- */
-public class JsStackEmulator {
-
- /**
- * Resets the global stack depth to the local stack index and top stack frame
- * after calls to Exceptions.caught. This is created by
- * {@link EntryExitVisitor#visit(JsCatch, JsContext)}.
- */
- private class CatchStackReset extends JsModVisitor {
-
- /**
- * The local stackIndex variable in the function.
- */
- private final EntryExitVisitor eeVisitor;
-
- public CatchStackReset(EntryExitVisitor eeVisitor) {
- this.eeVisitor = eeVisitor;
- }
-
- @Override
- public void endVisit(JsExprStmt x, JsContext<JsStatement> ctx) {
- // Looking for e = caught(e);
- JsExpression expr = x.getExpression();
-
- if (!(expr instanceof JsBinaryOperation)) {
- return;
- }
-
- JsBinaryOperation op = (JsBinaryOperation) expr;
- if (!(op.getArg2() instanceof JsInvocation)) {
- return;
- }
-
- JsInvocation i = (JsInvocation) op.getArg2();
- JsExpression q = i.getQualifier();
- if (!(q instanceof JsNameRef)) {
- return;
- }
-
- JsName name = ((JsNameRef) q).getName();
- if (name == null) {
- return;
- }
-
- // caughtFunction is the JsFunction translated from Exceptions.caught
- if (name.getStaticRef() != caughtFunction) {
- return;
- }
-
- // $stackDepth = stackIndex
- SourceInfo info = x.getSourceInfo().makeChild(JsStackEmulator.class,
- "Resetting stack depth");
- JsBinaryOperation reset = new JsBinaryOperation(info,
- JsBinaryOperator.ASG, stackDepth.makeRef(info),
- eeVisitor.stackIndexRef(info));
-
- ctx.insertAfter(reset.makeStmt());
- }
- }
-
- /**
- * The EntryExitVisitor handles pushing and popping frames onto the emulated
- * stack. It will operate on exactly one JsFunction. The basic transformation
- * is to add a push operation at every function entry, and then a pop
- * operation for every statement that might be the final statement executed by
- * the function.
- * <p>
- * General stack depth entry/exit code:
- *
- * <pre>
- * function foo() {
- * var stackIndex;
- * $stack[stackIndex = ++$stackDepth] = foo;
- *
- * ... do stuff ..
- *
- * $stackDepth = stackIndex - 1;
- * }
- * </pre>
- * <p>
- * For more complicated control flows involving return statements in try
- * blocks with as associated finally block, it is necessary to introduce a
- * local variable to indicate if control flow is expected to terminate
- * normally at the end of the finally block:
- *
- * <pre>
- * var exitingEarly;
- * try {
- * if (...) {
- * return (exitingEarly = true, new Foo());
- * }
- * ...
- * } finally {
- * ... existing finally code ..
- * exitingEarly && $stackDepth = stackIndex - 1;
- * }
- * </pre>
- * A separate local variable is used for each try/finally nested within a
- * finally block.
- * <p>
- * Try statements without a catch block will have a catch block added to them
- * so that catch blocks are the only places where flow-control may jump to.
- * All catch blocks are altered so that the global $stackDepth variable is
- * reset to the local stack index value. This allows browser-native exceptions
- * to be created with the correct stack trace before the finally code is
- * executed with a correct stack depth.
- *
- * <pre>
- * try {
- * foo();
- * } finally {
- * bar();
- * }
- * </pre>
- *
- * becomes
- *
- * <pre>
- * try {
- * foo();
- * } catch (e) {
- * e = caught(e);
- * $stackDepth = stackIndex;
- * throw e;
- * } finally {
- * bar();
- * }
- * <p>
- * Note that there is no specific handling for explicit throw statements, as
- * the stack instrumentation must also handle browser-generated exceptions
- * (e.g. <code>null.a()</code>).
- */
- private class EntryExitVisitor extends JsModVisitor {
-
- /**
- * The name of a function-local variable to hold the invocation's slot in
- * the stack.
- */
- protected JsName stackIndex;
-
- private final JsFunction currentFunction;
-
- /**
- * Maps finally blocks to the local variable name which is used to indicate
- * if that finally block will exit the function early. This is a map and not
- * a single value because a finally block might be nested in another exit
- * block.
- */
- private Map<JsBlock, JsName> finallyBlocksToExitVariables = Maps.create();
-
- /**
- * This variable will indicate the finally block that contains the last
- * statement that will be executed if an unconditional flow control change
- * were to occur within the associated try block.
- */
- private JsBlock outerFinallyBlock;
-
- /**
- * Used if a return statement's expression could potentially trigger an
- * exception.
- */
- private JsName returnTemp;
-
- /**
- * Final cleanup for any new local variables that need to be created.
- */
- private List<JsVar> varsToAdd = Lists.create();
-
- public EntryExitVisitor(JsFunction currentFunction) {
- this.currentFunction = currentFunction;
- }
-
- /**
- * If the visitor is exiting the current function's block, add additional
- * local variables and the final stack-pop instructions.
- */
- @Override
- public void endVisit(JsBlock x, JsContext<JsStatement> ctx) {
- if (x == currentFunction.getBody()) {
-
- // Add the entry code
- List<JsStatement> statements = x.getStatements();
- int idx = statements.isEmpty()
- || !(statements.get(0) instanceof JsVars) ? 0 : 1;
-
- // Add push and pop statements
- statements.add(idx, push(currentFunction));
- addPopAtEndOfBlock(x, false);
-
- // Add any needed variables
- JsVars vars;
- if (statements.get(0) instanceof JsVars) {
- vars = (JsVars) statements.get(0);
- } else {
- vars = new JsVars(currentFunction.getSourceInfo());
- statements.add(0, vars);
- }
- for (JsVar var : varsToAdd) {
- vars.add(var);
- }
- }
- }
-
- @Override
- public void endVisit(JsReturn x, JsContext<JsStatement> ctx) {
- if (outerFinallyBlock != null) {
- // 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));
- if (x.getExpr() == null) {
- if (ctx.canInsert()) {
- // exitingEarly = true; return;
- ctx.insertBefore(asg.makeStmt());
- } else {
- // {exitingEarly = true; return;}
- JsBlock block = new JsBlock(x.getSourceInfo());
- block.getStatements().add(asg.makeStmt());
- block.getStatements().add(x);
- ctx.replaceMe(block);
- }
- } else {
- // return (exitingEarly = true, expr);
- JsBinaryOperation op = new JsBinaryOperation(x.getSourceInfo(),
- JsBinaryOperator.COMMA, asg, x.getExpr());
- x.setExpr(op);
- }
- } else {
- if (x.getExpr() != null && x.getExpr().hasSideEffects()) {
- // temp = expr; pop(); return temp;
- SourceInfo info = x.getSourceInfo().makeChild(JsStackEmulator.class,
- "Flow break with side-effect");
- JsBinaryOperation asg = new JsBinaryOperation(info,
- JsBinaryOperator.ASG, returnTempRef(info), x.getExpr());
- x.setExpr(returnTempRef(info));
- pop(x, asg, ctx);
- } else {
- // Otherwise, pop the stack frame
- pop(x, null, ctx);
- }
- }
- }
-
- /**
- * We want to look at unaltered versions of the catch block, so this is a
- * <code>visit<code> and not a <code>endVisit</code>.
- */
- @Override
- public boolean visit(JsCatch x, JsContext<JsCatch> ctx) {
- // Reset the stack depth to the local index
- new CatchStackReset(this).accept(x);
- return true;
- }
-
- @Override
- public boolean visit(JsFunction x, JsContext<JsExpression> ctx) {
- // Will be taken care of by the Bootstrap visitor
- return false;
- }
-
- @Override
- public boolean visit(JsTry x, JsContext<JsStatement> ctx) {
-
- /*
- * Only the outermost finally block needs special treatment; try/finally
- * block within try blocks do not receive special treatment.
- */
- JsBlock finallyBlock = x.getFinallyBlock();
- if (finallyBlock != null && outerFinallyBlock == null) {
- outerFinallyBlock = finallyBlock;
-
- // Manual traversal
- accept(x.getTryBlock());
-
- if (x.getCatches().isEmpty()) {
- JsCatch c = makeSyntheticCatchBlock(x);
- x.getCatches().add(c);
- }
- assert x.getCatches().size() >= 1;
- acceptList(x.getCatches());
-
- // Exceptions in the finally block just exit the function
- assert outerFinallyBlock == finallyBlock;
- outerFinallyBlock = null;
- accept(finallyBlock);
-
- // Stack-pop instruction
- addPopAtEndOfBlock(finallyBlock, true);
-
- // Clean up entry after adding pop instruction
- finallyBlocksToExitVariables = Maps.remove(
- finallyBlocksToExitVariables, finallyBlock);
- return false;
- }
-
- // Normal visit
- return true;
- }
-
- /**
- * Create a reference to the function-local stack index variable, possibly
- * allocating it.
- */
- protected JsNameRef stackIndexRef(SourceInfo info) {
- if (stackIndex == null) {
- stackIndex = currentFunction.getScope().declareName(
- "JsStackEmulator_stackIndex", "stackIndex");
-
- JsVar var = new JsVar(info, stackIndex);
- varsToAdd = Lists.add(varsToAdd, var);
- }
- return stackIndex.makeRef(info);
- }
-
- /**
- * Code-gen function for generating the stack-pop statement at the end of a
- * block. A no-op if the last statement is a <code>throw</code> or
- * <code>return</code> statement, since it will have already caused a pop
- * statement to have been added.
- *
- * @param checkEarlyExit if <code>true</code>, generates
- * <code>earlyExit && pop()</code>
- */
- private void addPopAtEndOfBlock(JsBlock x, boolean checkEarlyExit) {
- JsStatement last = x.getStatements().isEmpty() ? null
- : x.getStatements().get(x.getStatements().size() - 1);
- if (last instanceof JsReturn || last instanceof JsThrow) {
- /*
- * Don't need a pop after a throw or break statement. This is an
- * optimization for the common case of returning a value as the last
- * statement, but doesn't cover all flow-control cases.
- */
- return;
- } else if (checkEarlyExit && !finallyBlocksToExitVariables.containsKey(x)) {
- /*
- * No early-exit variable was ever allocated for this block. This means
- * that the variable can never be true, and thus the stack-popping
- * expression will never be executed.
- */
- return;
- }
-
- // pop()
- SourceInfo info = x.getSourceInfo().makeChild(JsStackEmulator.class,
- "Stack exit");
- JsExpression op = pop(info);
-
- if (checkEarlyExit) {
- // earlyExit && pop()
- op = new JsBinaryOperation(info, JsBinaryOperator.AND, earlyExitRef(x),
- op);
- }
-
- x.getStatements().add(op.makeStmt());
- }
-
- /**
- * Generate a name reference to the early-exit variable for a given block,
- * possibly allocating a new variable.
- */
- private JsNameRef earlyExitRef(JsBlock x) {
- JsName earlyExitName = finallyBlocksToExitVariables.get(x);
- if (earlyExitName == null) {
- earlyExitName = currentFunction.getScope().declareName(
- "JsStackEmulator_exitingEarly"
- + finallyBlocksToExitVariables.size(), "exitingEarly");
-
- finallyBlocksToExitVariables = Maps.put(finallyBlocksToExitVariables,
- x, earlyExitName);
- JsVar var = new JsVar(x.getSourceInfo(), earlyExitName);
- varsToAdd = Lists.add(varsToAdd, var);
- }
- return earlyExitName.makeRef(x.getSourceInfo());
- }
-
- private JsCatch makeSyntheticCatchBlock(JsTry x) {
- /*
- * catch (e) { e = caught(e); throw e; }
- */
- SourceInfo info = x.getSourceInfo().makeChild(JsStackEmulator.class,
- "Synthetic catch block to fix stack depth");
-
- JsCatch c = new JsCatch(info, currentFunction.getScope(), "e");
- JsName paramName = c.getParameter().getName();
-
- // caught(e)
- JsInvocation caughtCall = new JsInvocation(info);
- caughtCall.setQualifier(caughtFunction.getName().makeRef(info));
- caughtCall.getArguments().add(paramName.makeRef(info));
-
- // e = caught(e)
- JsBinaryOperation asg = new JsBinaryOperation(info, JsBinaryOperator.ASG,
- paramName.makeRef(info), caughtCall);
-
- // throw e
- JsThrow throwStatement = new JsThrow(info, paramName.makeRef(info));
-
- JsBlock body = new JsBlock(info);
- body.getStatements().add(asg.makeStmt());
- body.getStatements().add(throwStatement);
- c.setBody(body);
- return c;
- }
-
- /**
- * Pops the stack frame.
- *
- * @param x the statement that will cause the pop
- * @param ctx the visitor context
- */
- private void pop(JsStatement x, JsExpression expr,
- JsContext<JsStatement> ctx) {
- // $stackDepth = stackIndex - 1
- SourceInfo info = x.getSourceInfo().makeChild(JsStackEmulator.class,
- "Stack exit");
-
- JsExpression op = pop(info);
-
- if (ctx.canInsert()) {
- if (expr != null) {
- ctx.insertBefore(expr.makeStmt());
- }
- ctx.insertBefore(op.makeStmt());
- } else {
- JsBlock block = new JsBlock(info);
- if (expr != null) {
- block.getStatements().add(expr.makeStmt());
- }
- block.getStatements().add(op.makeStmt());
- block.getStatements().add(x);
- ctx.replaceMe(block);
- }
- }
-
- /**
- * Decrement the $stackDepth variable.
- */
- private JsExpression pop(SourceInfo info) {
- JsBinaryOperation sub = new JsBinaryOperation(info, JsBinaryOperator.SUB,
- stackIndexRef(info), program.getNumberLiteral(1));
- JsBinaryOperation op = new JsBinaryOperation(info, JsBinaryOperator.ASG,
- stackDepth.makeRef(info), sub);
- return op;
- }
-
- /**
- * Create the function-entry code.
- */
- private JsStatement push(HasSourceInfo x) {
- SourceInfo info = x.getSourceInfo().makeChild(JsStackEmulator.class,
- "Stack entry code");
-
- JsNameRef stackRef = stack.makeRef(info);
- JsNameRef stackDepthRef = stackDepth.makeRef(info);
- JsExpression currentFunctionRef;
- if (currentFunction.getName() == null) {
- // Anonymous
- currentFunctionRef = program.getNullLiteral();
- } else {
- currentFunctionRef = currentFunction.getName().makeRef(info);
- }
-
- // ++stackDepth
- JsUnaryOperation inc = new JsPrefixOperation(info, JsUnaryOperator.INC,
- stackDepthRef);
-
- // stackIndex = ++stackDepth
- JsBinaryOperation stackIndexOp = new JsBinaryOperation(info,
- JsBinaryOperator.ASG, stackIndexRef(info), inc);
-
- // stack[stackIndex = ++stackDepth]
- JsArrayAccess access = new JsArrayAccess(info, stackRef, stackIndexOp);
-
- // stack[stackIndex = ++stackDepth] = currentFunction
- JsBinaryOperation op = new JsBinaryOperation(info, JsBinaryOperator.ASG,
- access, currentFunctionRef);
-
- return op.makeStmt();
- }
-
- private JsNameRef returnTempRef(SourceInfo info) {
- if (returnTemp == null) {
- returnTemp = currentFunction.getScope().declareName(
- "JsStackEmulator_returnTemp", "returnTemp");
-
- JsVar var = new JsVar(info, returnTemp);
- varsToAdd = Lists.add(varsToAdd, var);
- }
- return returnTemp.makeRef(info);
- }
- }
-
- /**
- * Creates a visitor to instrument each JsFunction in the program.
- */
- private class InstrumentAllFunctions extends JsVisitor {
- @Override
- public void endVisit(JsFunction x, JsContext<JsExpression> ctx) {
- if (!x.getBody().getStatements().isEmpty()) {
- if (recordLineNumbers) {
- (new LocationVisitor(x)).accept(x.getBody());
- } else {
- (new EntryExitVisitor(x)).accept(x.getBody());
- }
- }
- }
- }
-
- /**
- * Extends EntryExit visitor to record location information in the AST. This
- * visitor will modify every JsExpression that can potentially result in a
- * change of flow control with file and line number data.
- * <p>
- * This simply generates code to set entries in the <code>$location</code>
- * stack, parallel to <code>$stack</code>:
- *
- * <pre>
- * ($location[stackIndex] = 'Foo.java:' + 42, expr);
- * </pre>
- *
- * Inclusion of file names is dependent on the value of the
- * {@link JsStackEmulator#recordFileNames} field.
- */
- private class LocationVisitor extends EntryExitVisitor {
- private String lastFile;
- private int lastLine;
-
- public LocationVisitor(JsFunction function) {
- super(function);
- resetPosition();
- }
-
- @Override
- public void endVisit(JsArrayAccess x, JsContext<JsExpression> ctx) {
- record(x, ctx);
- }
-
- @Override
- public void endVisit(JsBinaryOperation x, JsContext<JsExpression> ctx) {
- if (x.getOperator().isAssignment()) {
- record(x, ctx);
- }
- }
-
- @Override
- public void endVisit(JsInvocation x, JsContext<JsExpression> ctx) {
- record(x, ctx);
- }
-
- @Override
- public void endVisit(JsNew x, JsContext<JsExpression> ctx) {
- record(x, ctx);
- }
-
- @Override
- public void endVisit(JsPostfixOperation x, JsContext<JsExpression> ctx) {
- if (x.getOperator().isModifying()) {
- record(x, ctx);
- }
- }
-
- @Override
- public void endVisit(JsPrefixOperation x, JsContext<JsExpression> ctx) {
- if (x.getOperator().isModifying()) {
- record(x, ctx);
- }
- }
-
- /**
- * This is essentially a hacked-up version of JsFor.traverse to account for
- * flow control differing from visitation order. It resets lastFile and
- * lastLine before the condition and increment expressions in the for loop
- * so that location data will be recorded correctly.
- */
- @Override
- public boolean visit(JsFor x, JsContext<JsStatement> ctx) {
- if (x.getInitExpr() != null) {
- x.setInitExpr(accept(x.getInitExpr()));
- } else if (x.getInitVars() != null) {
- x.setInitVars(accept(x.getInitVars()));
- }
-
- if (x.getCondition() != null) {
- resetPosition();
- x.setCondition(accept(x.getCondition()));
- }
-
- if (x.getIncrExpr() != null) {
- resetPosition();
- x.setIncrExpr(accept(x.getIncrExpr()));
- }
-
- accept(x.getBody());
- return false;
- }
-
- @Override
- public boolean visit(JsNameRef x, JsContext<JsExpression> ctx) {
- if (ctx.isLvalue()) {
- if (x.getQualifier() != null) {
- accept(x.getQualifier());
- }
- return false;
- }
- return true;
- }
-
- /**
- * Similar to JsFor, this resets the current location information before
- * evaluating the condition.
- */
- @Override
- public boolean visit(JsWhile x, JsContext<JsStatement> ctx) {
- resetPosition();
- x.setCondition(accept(x.getCondition()));
- accept(x.getBody());
- return false;
- }
-
- /**
- * Strips off the final name segment.
- */
- private String baseName(String fileName) {
- // Try the system path separator
- int lastIndex = fileName.lastIndexOf(File.separator);
- if (lastIndex == -1) {
- // Otherwise, try URL path separator
- lastIndex = fileName.lastIndexOf('/');
- }
- if (lastIndex != -1) {
- return fileName.substring(lastIndex + 1);
- } else {
- return fileName;
- }
- }
-
- private void record(JsExpression x, JsContext<JsExpression> ctx) {
- if (ctx.isLvalue()) {
- // Assignments to comma expressions aren't legal
- return;
- } else if (x.getSourceInfo().getStartLine() == lastLine
- && (!recordFileNames || x.getSourceInfo().getFileName().equals(
- lastFile))) {
- // Same location; ignore
- return;
- }
-
- SourceInfo info = x.getSourceInfo().makeChild(JsStackEmulator.class,
- "Synthetic location data");
-
- // ($locations[stackIndex] = fileName + lineNumber, x)
- JsExpression location = program.getStringLiteral(info,
- String.valueOf(lastLine = info.getStartLine()));
- if (recordFileNames) {
- // 'fileName:' + lineNumber
- JsStringLiteral stringLit = program.getStringLiteral(info,
- baseName(lastFile = info.getFileName()) + ":");
- location = new JsBinaryOperation(info, JsBinaryOperator.ADD, stringLit,
- location);
- }
-
- JsArrayAccess access = new JsArrayAccess(info, lineNumbers.makeRef(info),
- stackIndexRef(info));
- JsBinaryOperation asg = new JsBinaryOperation(info, JsBinaryOperator.ASG,
- access, location);
-
- JsBinaryOperation comma = new JsBinaryOperation(info,
- JsBinaryOperator.COMMA, asg, x);
-
- ctx.replaceMe(comma);
- }
-
- private void resetPosition() {
- lastFile = "";
- lastLine = -1;
- }
- }
-
- /**
- * The StackTraceCreator code refers to identifiers defined in JsRootScope,
- * which are unobfuscatable. This visitor replaces references to those symbols
- * with references to our locally-defined, obfuscatable names.
- */
- private class ReplaceUnobfuscatableNames extends JsModVisitor {
- // 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 = program.getRootScope().findExistingUnobfuscatableName(
- "$location");
-
- @Override
- public void endVisit(JsNameRef x, JsContext<JsExpression> ctx) {
- JsName name = x.getName();
- JsNameRef newRef = null;
-
- if (name == rootStack) {
- newRef = stack.makeRef(x.getSourceInfo());
- } else if (name == rootStackDepth) {
- newRef = stackDepth.makeRef(x.getSourceInfo());
- } else if (name == rootLineNumbers) {
- newRef = lineNumbers.makeRef(x.getSourceInfo());
- }
-
- if (newRef == null) {
- return;
- }
-
- assert x.getQualifier() == null;
- ctx.replaceMe(newRef);
- }
- }
-
- public static void exec(JsProgram program, PropertyOracle[] propertyOracles) {
- (new JsStackEmulator(program, propertyOracles)).execImpl();
- }
-
- private JsFunction caughtFunction;
- private JsName lineNumbers;
- private final JsProgram program;
- private boolean recordFileNames;
- private boolean recordLineNumbers;
- private JsName stack;
- private JsName stackDepth;
-
- private JsStackEmulator(JsProgram program, PropertyOracle[] propertyOracles) {
- this.program = program;
-
- assert propertyOracles.length > 0;
- PropertyOracle oracle = propertyOracles[0];
- try {
- List<String> values = oracle.getConfigurationProperty(
- "compiler.emulatedStack.recordFileNames").getValues();
- recordFileNames = Boolean.valueOf(values.get(0));
-
- values = oracle.getConfigurationProperty(
- "compiler.emulatedStack.recordLineNumbers").getValues();
- recordLineNumbers = recordFileNames || Boolean.valueOf(values.get(0));
- } catch (BadPropertyValueException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- private void execImpl() {
- caughtFunction = program.getIndexedFunction("Exceptions.caught");
- if (caughtFunction == null) {
- // No exceptions caught? Weird, but possible.
- return;
- }
- initNames();
- makeVars();
- (new ReplaceUnobfuscatableNames()).accept(program);
- (new InstrumentAllFunctions()).accept(program);
- }
-
- private void initNames() {
- stack = program.getScope().declareName("$JsStackEmulator_stack", "$stack");
- stackDepth = program.getScope().declareName("$JsStackEmulator_stackDepth",
- "$stackDepth");
- lineNumbers = program.getScope().declareName("$JsStackEmulator_location",
- "$location");
- }
-
- private void makeVars() {
- SourceInfo info = program.getSourceInfo().makeChild(JsStackEmulator.class,
- "Emulated stack data");
- JsVar stackVar = new JsVar(info, stack);
- stackVar.setInitExpr(new JsArrayLiteral(info));
- JsVar stackDepthVar = new JsVar(info, stackDepth);
- stackDepthVar.setInitExpr(program.getNumberLiteral(info, -1));
- JsVar lineNumbersVar = new JsVar(info, lineNumbers);
- lineNumbersVar.setInitExpr(new JsArrayLiteral(info));
-
- JsVars vars;
- JsStatement first = program.getGlobalBlock().getStatements().get(0);
- if (first instanceof JsVars) {
- vars = (JsVars) first;
- } else {
- vars = new JsVars(info);
- program.getGlobalBlock().getStatements().add(0, vars);
- }
- vars.add(stackVar);
- vars.add(stackDepthVar);
- vars.add(lineNumbersVar);
- }
-}
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 fde3094..dc073f9 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
@@ -44,8 +44,6 @@
*/
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>();
@@ -153,10 +151,6 @@
return getFragmentBlock(0);
}
- public JsFunction getIndexedFunction(String name) {
- return indexedFunctions.get(name);
- }
-
public JsNullLiteral getNullLiteral() {
return nullLiteral;
}
@@ -249,11 +243,6 @@
}
}
- public void setIndexedFunctions(Map<String, JsFunction> indexedFunctions) {
- this.indexedFunctions.clear();
- this.indexedFunctions.putAll(indexedFunctions);
- }
-
public void traverse(JsVisitor v, JsContext<JsProgram> ctx) {
if (v.visit(this, ctx)) {
for (JsProgramFragment fragment : fragments) {
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 815115f..30909ac 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
@@ -112,9 +112,6 @@
// GWT-defined identifiers
"$wnd", "$doc", "$moduleName", "$moduleBase", "$gwt_version",
- // Identifiers used by JsStackEmulator; later set to obfuscatable
- "$stack", "$stackDepth", "$location",
-
// TODO: prove why this is necessary or remove it
"call",};
diff --git a/tools/api-checker/build.xml b/tools/api-checker/build.xml
index da23606..5ee734f 100755
--- a/tools/api-checker/build.xml
+++ b/tools/api-checker/build.xml
@@ -10,10 +10,6 @@
<property.ensure name="gwt.dev.jar" location="${gwt.build.lib}/gwt-dev-${build.host.platform}.jar" />
<property.ensure name="gwt.user.jar" location="${gwt.build.lib}/gwt-user.jar" />
- <fileset id="default.tests" dir="${javac.junit.out}">
- <include name="**/*Test.class" />
- </fileset>
-
<target name="compile" description="Compile all class files">
<mkdir dir="${javac.out}" />
<gwt.javac>
@@ -24,7 +20,7 @@
</gwt.javac>
</target>
- <target name="compile.tests" depends="compile.emma" description="Compiles the test code for this project">
+ <target name="compile.tests" description="Compiles the test code for this project">
<mkdir dir="${javac.junit.out}" />
<gwt.javac srcdir="test" destdir="${javac.junit.out}">
<classpath>
@@ -46,12 +42,33 @@
</target>
<target name="test" depends="build, compile.tests" description="Run unit tests for this project.">
- <gwt.junit test.out="${junit.out}" test.cases="default.tests" >
- <extraclasspaths>
+ <taskdef name="junit" classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask">
+ <classpath>
+ <pathelement location="${gwt.tools.lib}/junit/junit-3.8.1.jar" />
+ <pathelement location="${gwt.tools.antlib}/ant-junit-1.6.5.jar" />
+ </classpath>
+ </taskdef>
+
+ <echo message="Writing test results to ${junit.out}/reports" />
+ <mkdir dir="${junit.out}/reports" />
+
+ <junit dir="${junit.out}" fork="yes" printsummary="yes" haltonfailure="true">
+ <sysproperty key="gwt.devjar" value="${gwt.dev.staging.jar}" />
+ <classpath>
+ <pathelement location="test" />
+ <pathelement location="${javac.junit.out}" />
<pathelement location="${gwt.build.out}/tools/api-checker/bin"/>
<pathelement location="${gwt.dev.jar}" />
- </extraclasspaths>
- </gwt.junit>
+ <pathelement location="${gwt.tools.lib}/junit/junit-3.8.1.jar" />
+ </classpath>
+
+ <formatter type="plain" />
+ <formatter type="xml" />
+ <batchtest todir="${junit.out}/reports">
+ <fileset dir="${javac.junit.out}"
+ includes="**/*Test.class"/>
+ </batchtest>
+ </junit>
</target>
<target name="checkstyle" description="Static analysis of source">
diff --git a/user/build.xml b/user/build.xml
index 1d2e3aa..3d687c5 100755
--- a/user/build.xml
+++ b/user/build.xml
@@ -3,14 +3,10 @@
<property name="project.tail" value="user" />
<property name="test.args" value="" />
- <!-- BrowserManagerServer_Stub compiled using rmic, which doesn't generate full source code -->
- <property name="emma.filter.exclude" value="*BrowserManagerServer_Stub*" />
-
<import file="${gwt.root}/common.ant.xml" />
<property name="gwt.junit.emmatestcase.includes" value="**/*Suite.class,com/google/gwt/dev/jjs/test/*Test.class"/>
<property name="test.timeout" value="3" />
- <property name="emma.merged.out" value="${junit.out}/emma-coverage" />
<!--
Whether I18NSuite should test e.g. Foo$InnerMsgs_fr.properties (if the
@@ -79,7 +75,7 @@
<gwt.ant dir="../dev/core" target="compile.tests" />
</target>
- <target name="compile.tests" depends="compile.dev.core.tests, compile.emma" description="Compiles the test code for this project">
+ <target name="compile.tests" depends="compile.dev.core.tests" description="Compiles the test code for this project">
<mkdir dir="${javac.junit.out}" />
<gwt.javac srcdir="test" excludes="com/google/gwt/langtest/**" destdir="${javac.junit.out}">
<classpath>
@@ -190,7 +186,6 @@
<target name="test" depends="compile, compile.tests" description="Run hosted-mode, web-mode, remoteweb, and selenium tests for this project.">
<property.ensure name="distro.built" location="${gwt.dev.staging.jar}" message="GWT must be built before performing any tests. This can be fixed by running ant in the ${gwt.root} directory." />
- <property name="emma.compiled" value="true" />
<!--
Run hosted and web mode tests for the platform on which this build
@@ -212,28 +207,6 @@
</limit>
</target>
- <target name="emma.merge" description="Merges coverage data for the entire project" if="emma.enabled">
- <delete dir="${emma.merged.out}" />
- <mkdir dir="${emma.merged.out}" />
- <emma>
- <merge outfile="${emma.merged.out}/merged.emma" >
- <fileset dir="${junit.out}" >
- <include name="**/*.emma" />
- <exclude name="${emma.merged.out}/merged.emma" />
- </fileset>
- </merge>
- </emma>
- <emma enabled="${emma.enabled}">
- <report sourcepath="${project.classpath.src}">
- <fileset file="${javac.emma.out}/metadata.emma" />
- <fileset file="${emma.merged.out}/merged.emma" />
- <txt outfile="${emma.merged.out}/coverage.txt" />
- <html outfile="${emma.merged.out}/coverage.html" />
- <xml outfile="${emma.merged.out}/coverage.xml" />
- </report>
- </emma>
- </target>
-
<target name="clean" description="Cleans this project's intermediate and output files">
<delete dir="${project.build}" />
<delete file="${project.lib}" />
diff --git a/user/src/com/google/gwt/core/CompilerParameters.gwt.xml b/user/src/com/google/gwt/core/CompilerParameters.gwt.xml
index d583502..f56fa77 100644
--- a/user/src/com/google/gwt/core/CompilerParameters.gwt.xml
+++ b/user/src/com/google/gwt/core/CompilerParameters.gwt.xml
@@ -22,14 +22,6 @@
<define-configuration-property name='compiler.splitpoint.initial.sequence'
is-multi-valued='true' />
- <!-- If set to true, this will add line number data to the stack trace data -->
- <define-configuration-property name="compiler.emulatedStack.recordLineNumbers"
- is-multi-valued="false" />
-
- <!-- Implies recordLineNumbers and adds source file name data to emitted JS -->
- <define-configuration-property name="compiler.emulatedStack.recordFileNames"
- is-multi-valued="false" />
-
<!-- From here down, the properties are unsupported and are only available for test cases -->
<!--
@@ -52,5 +44,5 @@
<define-configuration-property name="iframe.linker.script.chunk.size"
is-multi-valued="false" />
<set-configuration-property name="iframe.linker.script.chunk.size"
- value="30000" />
+ value="30000" />
</module>
diff --git a/user/src/com/google/gwt/core/EmulateJsStack.gwt.xml b/user/src/com/google/gwt/core/EmulateJsStack.gwt.xml
deleted file mode 100644
index 5e4b20f..0000000
--- a/user/src/com/google/gwt/core/EmulateJsStack.gwt.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- -->
-<!-- Copyright 2009 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 -->
-<!-- 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. License for the specific language governing permissions and -->
-<!-- limitations under the License. -->
-
-<!-- TODO(bobv): Implement the subset-of-permutation-matrix predicates -->
-<module>
- <inherits name="com.google.gwt.core.Core" />
- <replace-with
- class="com.google.gwt.core.client.impl.StackTraceCreator.CollectorEmulated">
- <when-type-is class="com.google.gwt.core.client.impl.StackTraceCreator.Collector" />
- </replace-with>
-</module>
diff --git a/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java b/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java
index 056cf51..6545297 100644
--- a/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java
+++ b/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java
@@ -108,9 +108,8 @@
/**
* A trivial queue of int's that should compile much better than a
- * LinkedList<Integer>. It assumes that it has a bound on the number of
- * items added to the queue. Removing items does not free up more space, but
- * calling <code>clear()</code> does.
+ * LinkedList<Integer>. It assumes that there will be a maximum number
+ * of items passed through the queue for its entire life.
*/
private static class BoundedIntQueue {
private final int[] array;
@@ -120,31 +119,22 @@
public BoundedIntQueue(int maxPuts) {
array = new int[maxPuts];
}
-
+
public void add(int x) {
assert (write < array.length);
array[write++] = x;
}
-
- /**
- * Removes all elements, and also makes all space in the queue available
- * again.
- */
- public void clear() {
- read = 0;
- write = 0;
- }
-
+
public int peek() {
assert read < write;
return array[read];
}
-
+
public int remove() {
assert read < write;
return array[read++];
}
-
+
public int size() {
return write - read;
}
@@ -188,12 +178,6 @@
waitingForInitialFragments.remove();
}
- /*
- * Call clear() here so that waitingForInitialFragments makes all of its
- * space available for later requests.
- */
- waitingForInitialFragments.clear();
-
// add handlers for pending initial fragment downloads
handlersToRun.addAll(initialFragmentErrorHandlers.values());
initialFragmentErrorHandlers.clear();
diff --git a/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java b/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java
index 3dc8a5e..42af02a 100644
--- a/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java
+++ b/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java
@@ -18,7 +18,6 @@
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;
/**
@@ -62,27 +61,6 @@
return toReturn;
}-*/;
- public void createStackTrace(JavaScriptException e) {
- JsArrayString stack = inferFrom(e.getException());
-
- StackTraceElement[] stackTrace = new StackTraceElement[stack.length()];
- for (int i = 0, j = stackTrace.length; i < j; i++) {
- stackTrace[i] = new StackTraceElement("Unknown", stack.get(i),
- "Unknown source", 0);
- }
- e.setStackTrace(stackTrace);
- }
-
- public void fillInStackTrace(Throwable t) {
- JsArrayString stack = StackTraceCreator.createStackTrace();
- StackTraceElement[] stackTrace = new StackTraceElement[stack.length()];
- for (int i = 0, j = stackTrace.length; i < j; i++) {
- stackTrace[i] = new StackTraceElement("Unknown", stack.get(i),
- "Unknown source", 0);
- }
- t.setStackTrace(stackTrace);
- }
-
/**
* Attempt to infer the stack from an unknown JavaScriptObject that had been
* thrown. The default implementation just returns an empty array.
@@ -112,72 +90,6 @@
}
/**
- * Collaborates with JsStackEmulator.
- */
- static class CollectorEmulated extends Collector {
-
- @Override
- public JsArrayString collect() {
- JsArrayString toReturn = JsArrayString.createArray().cast();
- JsArray<JavaScriptObject> stack = getStack();
- for (int i = 0, j = getStackDepth(); i < j; i++) {
- String name = stack.get(i) == null ? "anonymous"
- : extractName(stack.get(i).toString());
- // Reverse the order
- toReturn.set(j - i - 1, name);
- }
-
- return toReturn;
- }
-
- @Override
- public void createStackTrace(JavaScriptException e) {
- // No-op, relying on initializer call to collect()
- }
-
- public void fillInStackTrace(Throwable t) {
- JsArrayString stack = collect();
- JsArrayString locations = getLocation();
- StackTraceElement[] stackTrace = new StackTraceElement[stack.length()];
- for (int i = 0, j = stackTrace.length; i < j; i++) {
- // Locations is also backwards
- String location = locations.get(j - i - 1);
- String fileName = "Unknown source";
- int lineNumber = 0;
- if (location != null) {
- int idx = location.indexOf(':');
- if (idx != -1) {
- fileName = location.substring(0, idx);
- lineNumber = Integer.parseInt(location.substring(idx + 1));
- } else {
- lineNumber = Integer.parseInt(location);
- }
- }
- stackTrace[i] = new StackTraceElement("Unknown", stack.get(i),
- fileName, lineNumber);
- }
- t.setStackTrace(stackTrace);
- }
-
- @Override
- public JsArrayString inferFrom(JavaScriptObject e) {
- throw new RuntimeException("Should not reach here");
- }
-
- private native JsArrayString getLocation()/*-{
- return $location;
- }-*/;
-
- private native JsArray<JavaScriptObject> getStack()/*-{
- return $stack;
- }-*/;
-
- private native int getStackDepth() /*-{
- return $stackDepth;
- }-*/;
- }
-
- /**
* Mozilla provides a <code>stack</code> property in thrown objects.
*/
static class CollectorMoz extends Collector {
@@ -257,6 +169,19 @@
}
/**
+ * Create a stack trace based on the current execution stack. This method
+ * should only be called in web mode.
+ */
+ public static JsArrayString createStackTrace() {
+ if (!GWT.isScript()) {
+ throw new RuntimeException(
+ "StackTraceCreator should only be called in web mode");
+ }
+
+ return GWT.<Collector> create(Collector.class).collect();
+ }
+
+ /**
* Create a stack trace based on a JavaScriptException. This method should
* only be called in web mode.
*/
@@ -266,33 +191,15 @@
"StackTraceCreator should only be called in web mode");
}
- GWT.<Collector> create(Collector.class).createStackTrace(e);
- }
+ JsArrayString stack = GWT.<Collector> create(Collector.class).inferFrom(
+ e.getException());
- /**
- * Fill in a stack trace based on the current execution stack. This method
- * should only be called in web mode.
- */
- public static void fillInStackTrace(Throwable t) {
- if (!GWT.isScript()) {
- throw new RuntimeException(
- "StackTraceCreator should only be called in web mode");
+ StackTraceElement[] stackTrace = new StackTraceElement[stack.length()];
+ for (int i = 0, j = stackTrace.length; i < j; i++) {
+ stackTrace[i] = new StackTraceElement("Unknown", stack.get(i),
+ "Unknown source", 0);
}
-
- GWT.<Collector> create(Collector.class).fillInStackTrace(t);
- }
-
- /**
- * Create a stack trace based on the current execution stack. This method
- * should only be called in web mode.
- */
- static JsArrayString createStackTrace() {
- if (!GWT.isScript()) {
- throw new RuntimeException(
- "StackTraceCreator should only be called in web mode");
- }
-
- return GWT.<Collector> create(Collector.class).collect();
+ e.setStackTrace(stackTrace);
}
static String extractNameFromToString(String fnToString) {
diff --git a/user/src/com/google/gwt/junit/JUnit.gwt.xml b/user/src/com/google/gwt/junit/JUnit.gwt.xml
index 25a5abc..f351246 100644
--- a/user/src/com/google/gwt/junit/JUnit.gwt.xml
+++ b/user/src/com/google/gwt/junit/JUnit.gwt.xml
@@ -31,19 +31,6 @@
<when-type-assignable class="com.google.gwt.junit.client.GWTTestCase"/>
</generate-with>
- <!-- TODO(bobv): This is temporary until subset-of-permutation-matrix work is done. -->
- <!-- We want to provide good stack traces on browsers that don't provide good native stack traces. -->
- <set-configuration-property name="compiler.emulatedStack.recordFileNames" value="true" />
- <replace-with
- class="com.google.gwt.core.client.impl.StackTraceCreator.CollectorEmulated">
- <when-type-is class="com.google.gwt.core.client.impl.StackTraceCreator.Collector" />
- <none>
- <when-property-is name="user.agent" value="gecko" />
- <when-property-is name="user.agent" value="gecko1_8" />
- <when-property-is name="user.agent" value="opera" />
- </none>
- </replace-with>
-
<servlet path='/junithost' class='com.google.gwt.junit.server.JUnitHostImpl'/>
<inherits name="com.google.gwt.benchmarks.Benchmarks"/>
diff --git a/user/src/com/google/gwt/user/User.gwt.xml b/user/src/com/google/gwt/user/User.gwt.xml
index 2e31cd1..87c4bb7 100644
--- a/user/src/com/google/gwt/user/User.gwt.xml
+++ b/user/src/com/google/gwt/user/User.gwt.xml
@@ -21,7 +21,6 @@
<inherits name="com.google.gwt.core.Core"/>
<inherits name="com.google.gwt.event.Event"/>
<inherits name="com.google.gwt.animation.Animation"/>
- <inherits name="com.google.gwt.resources.Resources"/>
<inherits name="com.google.gwt.user.AsyncProxy"/>
<inherits name="com.google.gwt.user.RemoteService"/>
<inherits name="com.google.gwt.user.DocumentRoot" />
diff --git a/user/src/com/google/gwt/user/client/impl/WindowImplIE.java b/user/src/com/google/gwt/user/client/impl/WindowImplIE.java
index 386aa35..46ec347 100644
--- a/user/src/com/google/gwt/user/client/impl/WindowImplIE.java
+++ b/user/src/com/google/gwt/user/client/impl/WindowImplIE.java
@@ -18,8 +18,6 @@
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.ScriptElement;
-import com.google.gwt.resources.client.ClientBundle;
-import com.google.gwt.resources.client.TextResource;
import com.google.gwt.user.client.Command;
/**
@@ -28,31 +26,6 @@
public class WindowImplIE extends WindowImpl {
/**
- * The resources for this implementation.
- */
- public interface Resources extends ClientBundle {
- Resources INSTANCE = GWT.create(Resources.class);
-
- /**
- * Contains the function body used to initialize the window close handler.
- */
- @Source("initWindowCloseHandler.js")
- TextResource initWindowCloseHandler();
-
- /**
- * Contains the function body used to initialize the window resize handler.
- */
- @Source("initWindowResizeHandler.js")
- TextResource initWindowResizeHandler();
-
- /**
- * Contains the function body used to initialize the window scroll handler.
- */
- @Source("initWindowScrollHandler.js")
- TextResource initWindowScrollHandler();
- }
-
- /**
* For IE6, reading from $wnd.location.hash drops part of the fragment if the
* fragment contains a '?'. To avoid this bug, we use location.href instead.
*/
@@ -81,8 +54,8 @@
@Override
public void initWindowCloseHandler() {
- initHandler(Resources.INSTANCE.initWindowCloseHandler().getText(),
- new Command() {
+ initHandler(getWindowCloseHandlerMethodString(),
+ "__gwt_initWindowCloseHandler", new Command() {
public void execute() {
initWindowCloseHandlerImpl();
}
@@ -91,8 +64,8 @@
@Override
public void initWindowResizeHandler() {
- initHandler(Resources.INSTANCE.initWindowResizeHandler().getText(),
- new Command() {
+ initHandler(getWindowResizeHandlerMethodString(),
+ "__gwt_initWindowResizeHandler", new Command() {
public void execute() {
initWindowResizeHandlerImpl();
}
@@ -101,8 +74,8 @@
@Override
public void initWindowScrollHandler() {
- initHandler(Resources.INSTANCE.initWindowScrollHandler().getText(),
- new Command() {
+ initHandler(getWindowScrollHandlerMethodString(),
+ "__gwt_initWindowScrollHandler", new Command() {
public void execute() {
initWindowScrollHandlerImpl();
}
@@ -110,16 +83,110 @@
}
/**
+ * This method defines a function that sinks an event on the Window. However,
+ * this method returns the function as a String so it can be added to the
+ * outer window.
+ *
+ * We need to declare this method on the outer window because you cannot
+ * attach Window listeners from within an iframe on IE6.
+ *
+ * Per ECMAScript 262 spec 15.3.4.2, Function.prototype.toString() returns a
+ * string representation of the function that has the syntax of the function.
+ */
+ private native String getWindowCloseHandlerMethodString() /*-{
+ return function(beforeunload, unload) {
+ var wnd = window
+ , oldOnBeforeUnload = wnd.onbeforeunload
+ , oldOnUnload = wnd.onunload;
+
+ wnd.onbeforeunload = function(evt) {
+ var ret, oldRet;
+ try {
+ ret = beforeunload();
+ } finally {
+ oldRet = oldOnBeforeUnload && oldOnBeforeUnload(evt);
+ }
+ // Avoid returning null as IE6 will coerce it into a string.
+ // Ensure that "" gets returned properly.
+ if (ret != null) {
+ return ret;
+ }
+ if (oldRet != null) {
+ return oldRet;
+ }
+ // returns undefined.
+ };
+
+ wnd.onunload = function(evt) {
+ try {
+ unload();
+ } finally {
+ oldOnUnload && oldOnUnload(evt);
+ wnd.onresize = null;
+ wnd.onscroll = null;
+ wnd.onbeforeunload = null;
+ wnd.onunload = null;
+ }
+ };
+
+ // Remove the reference once we've initialize the handler
+ wnd.__gwt_initWindowCloseHandler = undefined;
+ }.toString();
+ }-*/;
+
+ /**
+ * @see #getWindowCloseHandlerMethodString()
+ */
+ private native String getWindowResizeHandlerMethodString() /*-{
+ return function(resize) {
+ var wnd = window, oldOnResize = wnd.onresize;
+
+ wnd.onresize = function(evt) {
+ try {
+ resize();
+ } finally {
+ oldOnResize && oldOnResize(evt);
+ }
+ };
+
+ // Remove the reference once we've initialize the handler
+ wnd.__gwt_initWindowResizeHandler = undefined;
+ }.toString();
+ }-*/;
+
+ /**
+ * @see #getWindowCloseHandlerMethodString()
+ */
+ private native String getWindowScrollHandlerMethodString() /*-{
+ return function(scroll) {
+ var wnd = window, oldOnScroll = wnd.onscroll;
+
+ wnd.onscroll = function(evt) {
+ try {
+ scroll();
+ } finally {
+ oldOnScroll && oldOnScroll(evt);
+ }
+ };
+
+ // Remove the reference once we've initialize the handler
+ wnd.__gwt_initWindowScrollHandler = undefined;
+ }.toString();
+ }-*/;
+
+ /**
* IE6 does not allow direct access to event handlers on the parent window,
* so we must embed a script in the parent window that will set the event
* handlers in the correct context.
*
* @param initFunc the string representation of the init function
+ * @param funcName the name to assign to the init function
* @param cmd the command to execute the init function
*/
- private void initHandler(String initFunc, Command cmd) {
+ private void initHandler(String initFunc, String funcName, Command cmd) {
if (GWT.isClient()) {
// Embed the init script on the page
+ initFunc = initFunc.replaceFirst("function", "function " + funcName);
ScriptElement scriptElem = Document.get().createScriptElement(initFunc);
Document.get().getBody().appendChild(scriptElem);
diff --git a/user/src/com/google/gwt/user/client/impl/initWindowCloseHandler.js b/user/src/com/google/gwt/user/client/impl/initWindowCloseHandler.js
deleted file mode 100644
index f0f923d..0000000
--- a/user/src/com/google/gwt/user/client/impl/initWindowCloseHandler.js
+++ /dev/null
@@ -1,38 +0,0 @@
-function __gwt_initWindowCloseHandler(beforeunload, unload) {
- var wnd = window
- , oldOnBeforeUnload = wnd.onbeforeunload
- , oldOnUnload = wnd.onunload;
-
- wnd.onbeforeunload = function(evt) {
- var ret, oldRet;
- try {
- ret = beforeunload();
- } finally {
- oldRet = oldOnBeforeUnload && oldOnBeforeUnload(evt);
- }
- // Avoid returning null as IE6 will coerce it into a string.
- // Ensure that "" gets returned properly.
- if (ret != null) {
- return ret;
- }
- if (oldRet != null) {
- return oldRet;
- }
- // returns undefined.
- };
-
- wnd.onunload = function(evt) {
- try {
- unload();
- } finally {
- oldOnUnload && oldOnUnload(evt);
- wnd.onresize = null;
- wnd.onscroll = null;
- wnd.onbeforeunload = null;
- wnd.onunload = null;
- }
- };
-
- // Remove the reference once we've initialize the handler
- wnd.__gwt_initWindowCloseHandler = undefined;
-}
diff --git a/user/src/com/google/gwt/user/client/impl/initWindowResizeHandler.js b/user/src/com/google/gwt/user/client/impl/initWindowResizeHandler.js
deleted file mode 100644
index f1631be..0000000
--- a/user/src/com/google/gwt/user/client/impl/initWindowResizeHandler.js
+++ /dev/null
@@ -1,14 +0,0 @@
-function __gwt_initWindowResizeHandler(resize) {
- var wnd = window, oldOnResize = wnd.onresize;
-
- wnd.onresize = function(evt) {
- try {
- resize();
- } finally {
- oldOnResize && oldOnResize(evt);
- }
- };
-
- // Remove the reference once we've initialize the handler
- wnd.__gwt_initWindowResizeHandler = undefined;
-}
diff --git a/user/src/com/google/gwt/user/client/impl/initWindowScrollHandler.js b/user/src/com/google/gwt/user/client/impl/initWindowScrollHandler.js
deleted file mode 100644
index 3713092..0000000
--- a/user/src/com/google/gwt/user/client/impl/initWindowScrollHandler.js
+++ /dev/null
@@ -1,14 +0,0 @@
-function __gwt_initWindowScrollHandler(scroll) {
- var wnd = window, oldOnScroll = wnd.onscroll;
-
- wnd.onscroll = function(evt) {
- try {
- scroll();
- } finally {
- oldOnScroll && oldOnScroll(evt);
- }
- };
-
- // Remove the reference once we've initialize the handler
- wnd.__gwt_initWindowScrollHandler = undefined;
-}
diff --git a/user/super/com/google/gwt/emul/java/lang/StackTraceElement.java b/user/super/com/google/gwt/emul/java/lang/StackTraceElement.java
index 1e40735..90abbba 100644
--- a/user/super/com/google/gwt/emul/java/lang/StackTraceElement.java
+++ b/user/super/com/google/gwt/emul/java/lang/StackTraceElement.java
@@ -18,7 +18,7 @@
import java.io.Serializable;
/**
- * Included for hosted mode source compatibility. Partially implemented
+ * Included for hosted mode source compatibility. Not yet implemented.
*
* @skip
*/
@@ -35,8 +35,8 @@
public StackTraceElement() {
}
- public StackTraceElement(String className, String methodName,
- String fileName, int lineNumber) {
+ public StackTraceElement(String className, String methodName, String fileName,
+ int lineNumber) {
this.className = className;
this.methodName = methodName;
this.fileName = fileName;
@@ -58,9 +58,4 @@
public String getMethodName() {
return methodName;
}
-
- public String toString() {
- return className + "." + methodName + "(" + fileName + ":" + lineNumber
- + ")";
- }
}
diff --git a/user/super/com/google/gwt/emul/java/lang/Throwable.java b/user/super/com/google/gwt/emul/java/lang/Throwable.java
index 633d8c7..b41223c 100644
--- a/user/super/com/google/gwt/emul/java/lang/Throwable.java
+++ b/user/super/com/google/gwt/emul/java/lang/Throwable.java
@@ -15,6 +15,7 @@
*/
package java.lang;
+import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.core.client.impl.StackTraceCreator;
import java.io.PrintStream;
@@ -69,7 +70,12 @@
* @return this
*/
public Throwable fillInStackTrace() {
- StackTraceCreator.fillInStackTrace(this);
+ JsArrayString stack = StackTraceCreator.createStackTrace();
+ stackTrace = new StackTraceElement[stack.length()];
+ for (int i = 0, j = stackTrace.length; i < j; i++) {
+ stackTrace[i] = new StackTraceElement("Unknown", stack.get(i),
+ "Unknown source", 0);
+ }
return this;
}
diff --git a/user/test/com/google/gwt/core/CoreSuite.java b/user/test/com/google/gwt/core/CoreSuite.java
index 397907d..659642f 100644
--- a/user/test/com/google/gwt/core/CoreSuite.java
+++ b/user/test/com/google/gwt/core/CoreSuite.java
@@ -20,7 +20,6 @@
import com.google.gwt.core.client.JavaScriptExceptionTest;
import com.google.gwt.core.client.JsArrayTest;
import com.google.gwt.core.client.impl.AsyncFragmentLoaderTest;
-import com.google.gwt.core.client.impl.EmulatedStackTraceTest;
import com.google.gwt.core.client.impl.StackTraceCreatorTest;
import com.google.gwt.junit.tools.GWTTestSuite;
@@ -39,7 +38,6 @@
suite.addTestSuite(JsArrayTest.class);
suite.addTestSuite(GWTTest.class);
suite.addTestSuite(StackTraceCreatorTest.class);
- suite.addTestSuite(EmulatedStackTraceTest.class);
suite.addTestSuite(AsyncFragmentLoaderTest.class);
// $JUnit-END$
diff --git a/user/test/com/google/gwt/core/client/impl/AsyncFragmentLoaderTest.java b/user/test/com/google/gwt/core/client/impl/AsyncFragmentLoaderTest.java
index 7e237e7..45f25b8 100644
--- a/user/test/com/google/gwt/core/client/impl/AsyncFragmentLoaderTest.java
+++ b/user/test/com/google/gwt/core/client/impl/AsyncFragmentLoaderTest.java
@@ -239,30 +239,6 @@
}
/**
- * This test catches a case in an earlier version of AsyncFragmentLoader where
- * AsyncFragmentLoader.waitingForInitialFragments could exhaust its available
- * space.
- */
- public void testOverflowInWaitingForInitialFragments() {
- MockLoadStrategy reqs = new MockLoadStrategy();
- int numEntries = 6;
- AsyncFragmentLoader loader = new AsyncFragmentLoader(numEntries, new int[] {
- 1, 2, 3}, reqs, NULL_LOGGER);
-
- /*
- * Repeatedly queue up extra downloads waiting on an initial and then fail.
- */
- for (int i = 0; i < 10; i++) {
- MockErrorHandler error = new MockErrorHandler();
- loader.inject(4, error);
- reqs.assertFragmentsRequested(1);
-
- loadFailed(reqs, 1);
- assertTrue(error.getWasCalled());
- }
- }
-
- /**
* A thorough exercise of loading with an initial load sequence specified.
*/
public void testWithInitialLoadSequence() {
diff --git a/user/test/com/google/gwt/core/client/impl/EmulatedStackTraceTest.java b/user/test/com/google/gwt/core/client/impl/EmulatedStackTraceTest.java
deleted file mode 100644
index edb633b..0000000
--- a/user/test/com/google/gwt/core/client/impl/EmulatedStackTraceTest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2009 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.core.client.impl;
-
-/**
- * Reuses the existing StackTraceCreatorTest, but forces emulated JS stack trace
- * code to be emitted..
- */
-public class EmulatedStackTraceTest extends StackTraceCreatorTest {
-
- @Override
- public String getModuleName() {
- return "com.google.gwt.core.EmulateJsStack";
- }
-
-}
diff --git a/user/test/com/google/gwt/core/client/impl/StackTraceCreatorTest.java b/user/test/com/google/gwt/core/client/impl/StackTraceCreatorTest.java
index 25545ba..c47fc6b 100644
--- a/user/test/com/google/gwt/core/client/impl/StackTraceCreatorTest.java
+++ b/user/test/com/google/gwt/core/client/impl/StackTraceCreatorTest.java
@@ -17,7 +17,6 @@
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptException;
-import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.junit.client.GWTTestCase;
@@ -27,7 +26,6 @@
*/
public class StackTraceCreatorTest extends GWTTestCase {
public static void testJavaScriptException() {
- JsArrayString start = sample();
Throwable t = null;
try {
throwNative();
@@ -54,9 +52,6 @@
}
checkStack(myName, t);
-
- JsArrayString end = sample();
- assertEquals(start, end);
}
/**
@@ -64,23 +59,16 @@
*/
public static void testReentrantCalls() {
if (!GWT.isScript()) {
- // sample is useless in hosted mode
+ // StackTraceCreator.createStackTrace() is useless in hosted mode
return;
}
- JsArrayString start = sample();
-
JsArrayString stack = countDown(5);
assertNotNull(stack);
assertTrue(stack.length() > 0);
-
- JsArrayString end = sample();
- assertEquals(start, end);
}
public static void testStackTraces() {
- JsArrayString start = sample();
-
Throwable t;
try {
throw new RuntimeException();
@@ -96,16 +84,6 @@
}
checkStack(myName, t);
-
- JsArrayString end = sample();
- assertEquals(start, end);
- }
-
- private static void assertEquals(JsArrayString start, JsArrayString end) {
- assertEquals("length", start.length(), end.length());
- for (int i = 0, j = start.length(); i < j; i++) {
- assertEquals("frame " + i, start.get(i), end.get(i));
- }
}
private static void checkStack(String myName, Throwable t) {
@@ -142,15 +120,7 @@
if (count > 0) {
return countDown(count - 1);
} else {
- return sample();
- }
- }
-
- private static JsArrayString sample() {
- if (GWT.isScript()) {
return StackTraceCreator.createStackTrace();
- } else {
- return JavaScriptObject.createArray().cast();
}
}