In cases where sourcemaps were turned off, or Safari is used, the StackTraceDeobfuscator would report the raw JS line number as the Java line number. This change does two things:
1) Enable CollectorChromeNoSourceMap which reports -1 for JS line number when sourcemaps are off (thus forcing symbolMap to be used)
2) If sourcemaps are on, but no column information is present, or column is -1 (Safari), fall back to symbolMap


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10862 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/core/CoreWithUserAgent.gwt.xml b/user/src/com/google/gwt/core/CoreWithUserAgent.gwt.xml
index f3b8dc5..f7b498e 100644
--- a/user/src/com/google/gwt/core/CoreWithUserAgent.gwt.xml
+++ b/user/src/com/google/gwt/core/CoreWithUserAgent.gwt.xml
@@ -19,14 +19,6 @@
   <inherits name="com.google.gwt.core.EmulateJsStack" />
   <inherits name="com.google.gwt.useragent.UserAgent"/>
 
-  <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.stackMode" value="native" />
-    <!-- For now, only Chrome provides Error.stack support, so we hijack the
-         entire WebKit permutation -->
-    <when-property-is name="user.agent" value="safari" />
-  </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.stackMode" value="native" />
@@ -54,6 +46,24 @@
     </none> 
   </set-property>
 
+  <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.stackMode" value="native" />
+    <!-- For now, only Chrome provides Error.stack support, so we hijack the
+         entire WebKit permutation -->
+    <when-property-is name="user.agent" value="safari" />
+    <when-property-is name="compiler.useSourceMaps" value="true"/>
+  </replace-with>
+
+  <replace-with class="com.google.gwt.core.client.impl.StackTraceCreator.CollectorChromeNoSourceMap">
+    <when-type-is class="com.google.gwt.core.client.impl.StackTraceCreator.Collector" />
+    <when-property-is name="compiler.stackMode" value="native" />
+    <!-- For now, only Chrome provides Error.stack support, so we hijack the
+         entire WebKit permutation -->
+    <when-property-is name="user.agent" value="safari" />
+    <when-property-is name="compiler.useSourceMaps" value="false"/>
+  </replace-with>
+
   <!-- Utility class to query if source maps are enabled, mainly for testing -->
   <replace-with class="com.google.gwt.core.client.impl.SourceMapProperty.SourceMapEnabled">
     <when-type-is class="com.google.gwt.core.client.impl.SourceMapProperty.SourceMapImpl"/>
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 78a0a5a..8fef66f 100644
--- a/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java
+++ b/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java
@@ -346,6 +346,10 @@
       return (toReturn.length() > 0 ? toReturn : "anonymous") + "@@" + location;
     }
 
+    protected int replaceIfNoSourceMap(int line) {
+         return line;
+    }
+
     @Override
     protected int toSplice() {
       return 3;
@@ -373,12 +377,22 @@
           }
         }
         stackTrace[i] = new StackTraceElement("Unknown", stackElements[0], fileName + "@" + col,
-            line < 0 ? -1 : line);
+            replaceIfNoSourceMap(line < 0 ? -1 : line));
       }
       e.setStackTrace(stackTrace);
     }
   }
 
+  /**
+   * Subclass that forces reported line numbers to -1 (fetch from symbolMap) if source maps are
+   * disabled.
+   */
+  static class CollectorChromeNoSourceMap extends CollectorChrome {
+    protected int replaceIfNoSourceMap(int line) {
+      return -1;
+    }
+  }
+
   private static native int parseInt(String number) /*-{
     return parseInt(number) || -1;
   }-*/;
diff --git a/user/src/com/google/gwt/logging/server/StackTraceDeobfuscator.java b/user/src/com/google/gwt/logging/server/StackTraceDeobfuscator.java
index 05e7ec3..e82e963 100644
--- a/user/src/com/google/gwt/logging/server/StackTraceDeobfuscator.java
+++ b/user/src/com/google/gwt/logging/server/StackTraceDeobfuscator.java
@@ -17,12 +17,9 @@
 package com.google.gwt.logging.server;
 
 import com.google.gwt.thirdparty.debugging.sourcemap.SourceMapConsumerFactory;
-import com.google.gwt.thirdparty.debugging.sourcemap.SourceMapConsumerV3;
 import com.google.gwt.thirdparty.debugging.sourcemap.SourceMapping;
 import com.google.gwt.thirdparty.debugging.sourcemap.proto.Mapping;
 
-import org.json.JSONObject;
-
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
@@ -136,6 +133,22 @@
     SymbolMap map = loadSymbolMap(strongName);
     String symbolData = map == null ? null : map.get(ste.getMethodName());
 
+    boolean sourceMapCapable = false;
+
+    int column = 1;
+    // column information is encoded in filename after '@' for sourceMap capable browsers
+    if (steFilename != null) {
+      int columnMarkerIndex = steFilename.indexOf("@");
+      if (columnMarkerIndex != -1) {
+        try {
+          column = Integer.parseInt(steFilename.substring(columnMarkerIndex + 1));
+          sourceMapCapable = true;
+        } catch (NumberFormatException nfe) {
+        }
+        steFilename = steFilename.substring(0, columnMarkerIndex);
+      }
+    }
+
     // first use symbolMap, then refine via sourceMap if possible
     if (symbolData != null) {
       // jsniIdent, className, memberName, sourceUri, sourceLine, fragmentId
@@ -164,7 +177,8 @@
          * compiler.emulatedStack.recordLineNumbers is false, use the method
          * declaration line number from the symbol map.
          */
-        if (lineNumber == LINE_NUMBER_UNKNOWN) {
+        if (lineNumber == LINE_NUMBER_UNKNOWN || (sourceMapCapable && column == -1)) {
+          // Safari will send line numbers, with col == -1, we need to use symbolMap in this case
           lineNumber = Integer.parseInt(parts[4]);
         }
 
@@ -172,20 +186,7 @@
       }
     }
 
-    int column = 1;
-    // column information is encoded in filename after '@'
-    if (steFilename != null) {
-      int columnMarkerIndex = steFilename.indexOf("@");
-      if (columnMarkerIndex != -1) {
-        try {
-          column = Integer.parseInt(steFilename.substring(columnMarkerIndex + 1));
-        } catch (NumberFormatException nfe) {
-        }
-        steFilename = steFilename.substring(0, columnMarkerIndex);
-      }
-    }
-
-    // anonymous function, try to use <fragmentNum>.js:line:col to lookup function
+    // anonymous function, try to use <fragmentNum>.js:line to determine fragment id
     if (fragmentId == -1 && steFilename != null) {
       // fragment identifier encoded in filename
       Matcher matcher = fragmentIdPattern.matcher(steFilename);
@@ -205,7 +206,7 @@
     int jsLineNumber = ste.getLineNumber();
 
     // try to refine location via sourcemap
-    if (fragmentId != -1) {
+    if (sourceMapCapable && fragmentId != -1 && column != -1) {
       SourceMapping sourceMapping = loadSourceMap(strongName, fragmentId);
       if (sourceMapping != null && ste.getLineNumber() > -1) {
         Mapping.OriginalMapping mappingForLine = sourceMapping