Revision: 5979
Author: [email protected]
Date: Thu Aug 20 05:47:14 2009
Log: Add a stack trace collector for Chrome.
This is mapped into the webkit user.agent, but will fall back to the  
standard collector when running on Safari.

Patch by: schuck
Review by: bobv
http://code.google.com/p/google-web-toolkit/source/detail?r=5979

Modified:
  /trunk/user/src/com/google/gwt/core/CoreWithUserAgent.gwt.xml
  /trunk/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java
  /trunk/user/test/com/google/gwt/core/client/impl/StackTraceCreatorTest.java

=======================================
--- /trunk/user/src/com/google/gwt/core/CoreWithUserAgent.gwt.xml       Mon Aug 
 
17 09:47:48 2009
+++ /trunk/user/src/com/google/gwt/core/CoreWithUserAgent.gwt.xml       Thu Aug 
 
20 05:47:14 2009
@@ -15,7 +15,17 @@
  <!-- Deferred binding rules for core classes based on user agent. -->
  <module>
    <inherits name="com.google.gwt.core.Core"/>
-
+
+  <replace-with  
class="com.google.gwt.core.client.impl.StackTraceCreator.CollectorChrome">
+    <when-type-is  
class="com.google.gwt.core.client.impl.StackTraceCreator.Collector" />
+    <when-property-is name="compiler.emulatedStack" value="false" />
+    <any>
+      <!-- For now, only Chrome provides Error.stack support, so we hijack  
the
+           entire WebKit permutation -->
+      <when-property-is name="user.agent" value="safari" />
+    </any>
+  </replace-with>
+
    <replace-with  
class="com.google.gwt.core.client.impl.StackTraceCreator.CollectorMoz">
      <when-type-is  
class="com.google.gwt.core.client.impl.StackTraceCreator.Collector" />
      <when-property-is name="compiler.emulatedStack" value="false" />
=======================================
--- /trunk/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java      
 
Tue Jul 28 09:27:08 2009
+++ /trunk/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java      
 
Thu Aug 20 05:47:14 2009
@@ -207,6 +207,88 @@
        return 2;
      }
    }
+
+  /**
+   * Chrome uses a slightly different format to Mozilla.
+   *
+   * See  
http://code.google.com/p/v8/source/browse/branches/bleeding_edge/src/
+   * messages.js?r=2340#712 for formatting code.
+   *
+   * Function calls can be of the four following forms:
+   *
+   * <pre>
+   * at file.js:1:2
+   * at functionName (file.js:1:2)
+   * at Type.functionName (file.js:1:2)
+   * at Type.functionName [as methodName] (file.js:1:2)
+   * </pre>
+   */
+  static class CollectorChrome extends CollectorMoz {
+    @Override
+    public JsArrayString collect() {
+      JsArrayString res = super.collect();
+      if (res.length() == 0) {
+        /*
+         * Ensure Safari falls back to default Collector implementation.
+         * Remember to remove this method call from the stack:
+         */
+        res = splice(new Collector().collect(), 1);
+      }
+      return res;
+    }
+
+    @Override
+    public JsArrayString inferFrom(JavaScriptObject e) {
+      JsArrayString stack = super.inferFrom(e);
+      if (stack.length() == 0) {
+        // Safari should fall back to default Collector:
+        return new Collector().inferFrom(e);
+      } else {
+        // Chrome contains the error itself as the first line of the stack:
+        return splice(stack, 1);
+      }
+    }
+
+    @Override
+    protected String extractName(String fnToString) {
+      if (fnToString.length() == 0) {
+        return "anonymous";
+      }
+
+      String toReturn = fnToString.trim();
+
+      // Strip the "at " prefix:
+      if (toReturn.startsWith("at ")) {
+        toReturn = toReturn.substring(3);
+      }
+
+      // Strip bracketed items from the end:
+      int index = toReturn.indexOf("[");
+      if (index == -1) {
+        index = toReturn.indexOf("(");
+      }
+      if (index == -1) {
+        // No bracketed items found, hence no function name available:
+        return "anonymous";
+      } else {
+        // Bracketed items found: strip them off.
+        toReturn = toReturn.substring(0, index).trim();
+      }
+
+      // Strip the Type off to leave just the functionName:
+      index = toReturn.indexOf('.');
+      if (index != -1) {
+        toReturn = toReturn.substring(index + 1);
+      }
+
+      return toReturn.length() > 0 ? toReturn : "anonymous";
+    }
+
+    @Override
+    protected int toSplice() {
+      return 3;
+    }
+  }

    /**
     * Opera encodes stack trace information in the error's message.
=======================================
---  
/trunk/user/test/com/google/gwt/core/client/impl/StackTraceCreatorTest.java     
 
Thu Jul 30 13:47:31 2009
+++  
/trunk/user/test/com/google/gwt/core/client/impl/StackTraceCreatorTest.java     
 
Thu Aug 20 05:47:14 2009
@@ -19,6 +19,7 @@
  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.core.client.impl.StackTraceCreator.CollectorChrome;
  import com.google.gwt.junit.DoNotRunWith;
  import com.google.gwt.junit.Platform;
  import com.google.gwt.junit.client.GWTTestCase;
@@ -64,7 +65,7 @@
    /**
     * Just make sure that reentrant behavior doesn't fail.
     */
-  @DoNotRunWith({Platform.Htmlunit})
+  @DoNotRunWith(value = {Platform.Htmlunit})
    public static void testReentrantCalls() {
      if (!GWT.isScript()) {
        // sample is useless in hosted mode
@@ -81,7 +82,7 @@
      assertEquals(start, end);
    }

-  @DoNotRunWith({Platform.Htmlunit})
+  @DoNotRunWith(value = {Platform.Htmlunit})
    public static void testStackTraces() {
      JsArrayString start = sample();

@@ -193,4 +194,16 @@
      assertEquals("foo",
          StackTraceCreator.extractNameFromToString("  function foo (){}"));
    }
-}
+
+  public void testChromeExtractName() {
+    CollectorChrome c = new CollectorChrome();
+
+    assertEquals("anonymous", c.extractName(" at file.js:1:2"));
+    assertEquals("functionName",
+        c.extractName(" at functionName (file.js:1:2)"));
+    assertEquals("functionName",
+        c.extractName(" at Type.functionName (file.js:1:2)"));
+    assertEquals("functionName",
+        c.extractName(" at Type.functionName [as methodName]  
(file.js:1:2)"));
+  }
+}

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to