Add sourcemap support to super dev mode. Source files work in Chrome canary
for everything except for super source. Also, enable super dev mode for
TourGuide's gin sample.
(This is a cleaned-up version of cromwellian's patch for the GWT summit.)
Review by: cromwellian@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10836 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/js/JsReportGenerationVisitor.java b/dev/core/src/com/google/gwt/dev/js/JsReportGenerationVisitor.java
index 5d4441b..8e90c2c 100644
--- a/dev/core/src/com/google/gwt/dev/js/JsReportGenerationVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/js/JsReportGenerationVisitor.java
@@ -18,7 +18,10 @@
import com.google.gwt.core.ext.soyc.Range;
import com.google.gwt.dev.jjs.HasSourceInfo;
import com.google.gwt.dev.jjs.SourceInfo;
+import com.google.gwt.dev.jjs.SourceOrigin;
+import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.impl.JavaToJavaScriptMap;
+import com.google.gwt.dev.js.ast.JsName;
import com.google.gwt.dev.js.ast.JsVisitable;
import com.google.gwt.dev.util.TextOutput;
@@ -42,23 +45,33 @@
}
@Override
- public Map<Range, SourceInfo> getSourceInfoMap() {
- return Collections.unmodifiableMap(sourceInfoMap);
+ protected <T extends JsVisitable> T generateAndBill(T node, JsName nameToBillTo) {
+
+ if (!(node instanceof HasSourceInfo)) {
+ return super.generateAndBill(node, nameToBillTo);
+ }
+
+ // Remember the position before generating the JavaScript.
+ int beforePosition = out.getPosition();
+ int beforeLine = out.getLine();
+ int beforeColumn = out.getColumn();
+
+ // Write some JavaScript (changing the position).
+ T toReturn = super.generateAndBill(node, nameToBillTo);
+
+ Range javaScriptRange = new Range(beforePosition, out.getPosition(),
+ beforeLine, beforeColumn, out.getLine(), out.getColumn());
+
+ SourceInfo defaultTarget = ((HasSourceInfo) node).getSourceInfo();
+ SourceInfo newTarget = findTarget(nameToBillTo, defaultTarget);
+ sourceInfoMap.put(javaScriptRange, newTarget);
+
+ return toReturn;
}
@Override
- protected <T extends JsVisitable> T doAccept(T node) {
- boolean addEntry = node instanceof HasSourceInfo;
- int start = addEntry ? out.getPosition() : 0;
- int sLine = out.getLine();
- int sCol = out.getColumn();
- T toReturn = super.doAccept(node);
- if (addEntry) {
- SourceInfo info = ((HasSourceInfo) node).getSourceInfo();
- sourceInfoMap.put(new Range(start, out.getPosition(),
- sLine, sCol, out.getLine(), out.getColumn()), info);
- }
- return toReturn;
+ public Map<Range, SourceInfo> getSourceInfoMap() {
+ return Collections.unmodifiableMap(sourceInfoMap);
}
@Override
@@ -75,4 +88,39 @@
doAccept(t);
}
}
+
+ /**
+ * Finds the Java filename and line number that we want in the source map.
+ * (This needs to be a relative path that makes sense as a URL.)
+ */
+ private SourceInfo findTarget(JsName nameToBillTo, SourceInfo defaultTarget) {
+ String newFilename = findTargetFile(nameToBillTo, defaultTarget.getFileName());
+
+ if (newFilename == defaultTarget.getFileName()) {
+ return defaultTarget;
+ } else {
+ return SourceOrigin.create(defaultTarget.getStartLine(), newFilename);
+ }
+ }
+
+ /**
+ * Finds the name of the Java file that we want to put in the source map.
+ */
+ private String findTargetFile(JsName nameToBillTo, String defaultFilename) {
+ // For the filename, we really want the path passed to ResourceLoader.getResource().
+ // But for now, fake it based on the type name.
+ // TODO(skybrian): fix
+
+ JDeclaredType type = getDirectlyEnclosingType(nameToBillTo);
+ if (type == null) {
+ return defaultFilename;
+ }
+
+ // remove inner classes
+ while (type.getEnclosingType() != null) {
+ type = type.getEnclosingType();
+ }
+
+ return type.getName().replace('.', '/') + ".java";
+ }
}
diff --git a/dev/core/src/com/google/gwt/dev/js/JsSourceGenerationVisitorWithSizeBreakdown.java b/dev/core/src/com/google/gwt/dev/js/JsSourceGenerationVisitorWithSizeBreakdown.java
index f123b0f..e471cc3 100644
--- a/dev/core/src/com/google/gwt/dev/js/JsSourceGenerationVisitorWithSizeBreakdown.java
+++ b/dev/core/src/com/google/gwt/dev/js/JsSourceGenerationVisitorWithSizeBreakdown.java
@@ -18,6 +18,8 @@
import com.google.gwt.core.ext.soyc.Range;
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.jjs.ast.JClassType;
+import com.google.gwt.dev.jjs.ast.JDeclaredType;
+import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.impl.FragmentExtractor;
import com.google.gwt.dev.jjs.impl.JavaToJavaScriptMap;
@@ -28,8 +30,8 @@
import com.google.gwt.dev.js.ast.JsProgramFragment;
import com.google.gwt.dev.js.ast.JsSeedIdOf;
import com.google.gwt.dev.js.ast.JsStatement;
-import com.google.gwt.dev.js.ast.JsVisitable;
import com.google.gwt.dev.js.ast.JsVars.JsVar;
+import com.google.gwt.dev.js.ast.JsVisitable;
import com.google.gwt.dev.util.TextOutput;
import com.google.gwt.dev.util.collect.HashMap;
@@ -43,8 +45,8 @@
public class JsSourceGenerationVisitorWithSizeBreakdown extends
JsSourceGenerationVisitor {
- private final JavaToJavaScriptMap map;
- private JsName nameToBillTo;
+ private JavaToJavaScriptMap map;
+ private JsName billedAncestor; // non-null when an ancestor is also being billed
private TextOutput out;
private final Map<JsName, Integer> sizeMap = new HashMap<JsName, Integer>();
@@ -89,19 +91,9 @@
}
@Override
- protected <T extends JsVisitable> T doAccept(T node) {
- JsName newName = nameToBillTo(node);
- if (newName == null) {
- return super.doAccept(node);
- } else {
- JsName oldName = nameToBillTo;
- nameToBillTo = newName;
- int start = out.getPosition();
- T retValue = super.doAccept(node);
- billChars(nameToBillTo, out.getPosition() - start);
- nameToBillTo = oldName;
- return retValue;
- }
+ protected final <T extends JsVisitable> T doAccept(T node) {
+ JsName newName = nameToBillTo(node, billedAncestor != null);
+ return generateAndBill(node, newName);
}
@Override
@@ -119,6 +111,48 @@
}
}
+ /**
+ * Generate some JavaScript and bill the number of characters generated to the given name.
+ */
+ protected <T extends JsVisitable> T generateAndBill(T node, JsName nameToBillTo) {
+ if (nameToBillTo == null) {
+ return super.doAccept(node);
+ } else {
+ int start = out.getPosition();
+
+ JsName savedAncestor = billedAncestor;
+ billedAncestor = nameToBillTo;
+ T retValue = super.doAccept(node);
+ billedAncestor = savedAncestor;
+
+ billChars(nameToBillTo, out.getPosition() - start);
+ return retValue;
+ }
+ }
+
+ protected JDeclaredType getDirectlyEnclosingType(JsName nameToBillTo) {
+ if (nameToBillTo == null) {
+ return null;
+ }
+
+ JDeclaredType type = map.nameToType(nameToBillTo);
+ if (type != null) {
+ return type;
+ }
+
+ JMethod method = map.nameToMethod(nameToBillTo);
+ if (method != null) {
+ return method.getEnclosingType();
+ }
+
+ JField field = map.nameToField(nameToBillTo);
+ if (field != null) {
+ return field.getEnclosingType();
+ }
+
+ return null;
+ }
+
private void billChars(JsName nameToBillTo, int chars) {
Integer oldSize = sizeMap.get(nameToBillTo);
if (oldSize == null) {
@@ -128,10 +162,10 @@
}
/**
- * If parameter is JsVisitable, javac version sun jdk1.6.0 complains about
- * incompatible types.
+ * Returns the type, function, or variable name where this node's character count
+ * should be added, or null to bill to nobody.
*/
- private JsName nameToBillTo(JsVisitable node) {
+ private JsName nameToBillTo(JsVisitable node, boolean isAncestorBilled) {
if (node instanceof JsStatement) {
JsStatement stat = (JsStatement) node;
JClassType type = map.typeForStatement(stat);
@@ -143,12 +177,11 @@
if (method != null) {
return map.nameForMethod(method);
}
- }
- if (node instanceof JsVar) {
- if (nameToBillTo == null) {
- return ((JsVar) node).getName();
- }
+ return null;
+
+ } else if (node instanceof JsVar) {
+ return isAncestorBilled ? null : ((JsVar) node).getName(); // handle top-level vars
}
return null;
diff --git a/user/src/com/google/gwt/core/CoreWithUserAgent.gwt.xml b/user/src/com/google/gwt/core/CoreWithUserAgent.gwt.xml
index a829874..3384a1b 100644
--- a/user/src/com/google/gwt/core/CoreWithUserAgent.gwt.xml
+++ b/user/src/com/google/gwt/core/CoreWithUserAgent.gwt.xml
@@ -51,8 +51,6 @@
</none>
</set-property>
-<set-property name="compiler.useSourceMaps" value="false"/>
-
<!-- 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"/>