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

Reply via email to