Reviewers: bobv,
Description:
This patch fixes issue 4512:
http://code.google.com/p/google-web-toolkit/issues/detail?id=4512
The problem is that bar['foo']() sets "this" to be whatever "bar" is,
but that doesn't happen if bar['foo'] is rewritten for stack tracing.
There is a replication case on the bug report.
This patch simply skips any rewrite of an expression that is invoked as
a function.
Please review this at http://gwt-code-reviews.appspot.com/132815
Affected files:
dev/core/src/com/google/gwt/dev/js/JsStackEmulator.java
Index: dev/core/src/com/google/gwt/dev/js/JsStackEmulator.java
===================================================================
--- dev/core/src/com/google/gwt/dev/js/JsStackEmulator.java (revision 7430)
+++ dev/core/src/com/google/gwt/dev/js/JsStackEmulator.java (working copy)
@@ -38,6 +38,7 @@
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.JsNode;
import com.google.gwt.dev.js.ast.JsPostfixOperation;
import com.google.gwt.dev.js.ast.JsPrefixOperation;
import com.google.gwt.dev.js.ast.JsProgram;
@@ -56,8 +57,10 @@
import com.google.gwt.dev.util.collect.Maps;
import java.io.File;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Emulates the JS stack in order to provide useful stack traces on
browers that
@@ -67,8 +70,6 @@
*/
public class JsStackEmulator {
- private static final String PROPERTY_NAME = "compiler.emulatedStack";
-
/**
* Resets the global stack depth to the local stack index and top stack
frame
* after calls to Exceptions.caught. This is created by
@@ -590,6 +591,7 @@
* {...@link JsStackEmulator#recordFileNames} field.
*/
private class LocationVisitor extends EntryExitVisitor {
+ private final Set<JsNode<?>> invokedNodes = new HashSet<JsNode<?>>();
private String lastFile;
private int lastLine;
@@ -612,6 +614,7 @@
@Override
public void endVisit(JsInvocation x, JsContext<JsExpression> ctx) {
+ invokedNodes.remove(x.getQualifier());
record(x, ctx);
}
@@ -663,6 +666,12 @@
}
@Override
+ public boolean visit(JsInvocation x, JsContext<JsExpression> ctx) {
+ invokedNodes.add(x.getQualifier());
+ return true;
+ }
+
+ @Override
public boolean visit(JsNameRef x, JsContext<JsExpression> ctx) {
if (ctx.isLvalue()) {
if (x.getQualifier() != null) {
@@ -706,6 +715,9 @@
if (ctx.isLvalue()) {
// Assignments to comma expressions aren't legal
return;
+ } else if (invokedNodes.contains(x)) {
+ // Don't modify invokees, because their syntax affects the value
of "this"
+ return;
} else if (x.getSourceInfo().getStartLine() == lastLine
&& (!recordFileNames || x.getSourceInfo().getFileName().equals(
lastFile))) {
@@ -750,13 +762,13 @@
* 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 =
program.getRootScope().findExistingUnobfuscatableName(
- "$location");
@Override
public void endVisit(JsNameRef x, JsContext<JsExpression> ctx) {
@@ -780,6 +792,8 @@
}
}
+ private static final String PROPERTY_NAME = "compiler.emulatedStack";
+
public static void exec(JsProgram program, PropertyOracle[]
propertyOracles) {
SelectionProperty property;
try {
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors