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 -~----------~----~----~----~------~----~------~--~---
