Change how source map filenames get calculated. This is now controlled
by CompilationUnitBuilder.getSourceMapPath(). Filenames in source maps
are now relative to the classpath, except in the case of files created
by generators, which have filenames in a synthetic "gen/" directory.
Filenames under the gen/ directory should correspond to what the
filename would be in a -gen directory, regardless of whether the user
passes the -gen option to the compiler.
I'm not changing the filenames in the JDT for now, so filenames in
most error messages are unaffected and sometimes will be different
from the name in the source map. (I don't understand the consequences
of making that change, so it's safer to do it separately.)
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10873 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java b/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
index c3598ac..228b2a9 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
@@ -70,8 +70,8 @@
Event event = SpeedTracerLogger.start(DevModeEventType.CSB_PROCESS);
try {
Map<MethodDeclaration, JsniMethod> jsniMethods =
- JsniCollector.collectJsniMethods(cud, builder.getSource(), JsRootScope.INSTANCE,
- DummyCorrelationFactory.INSTANCE);
+ JsniCollector.collectJsniMethods(cud, builder.getSourceMapPath(),
+ builder.getSource(), JsRootScope.INSTANCE, DummyCorrelationFactory.INSTANCE);
JSORestrictionsChecker.check(jsoState, cud);
@@ -94,7 +94,8 @@
ArtificialRescueChecker.check(cud, builder.isGenerated(), artificialRescues);
BinaryTypeReferenceRestrictionsChecker.check(cud);
- MethodArgNamesLookup methodArgs = MethodParamCollector.collect(cud);
+ MethodArgNamesLookup methodArgs = MethodParamCollector.collect(cud,
+ builder.getSourceMapPath());
StringInterner interner = StringInterner.get();
String packageName = interner.intern(Shared.getPackageName(builder.getTypeName()));
@@ -119,7 +120,8 @@
List<JDeclaredType> types = Collections.emptyList();
if (!cud.compilationResult().hasErrors()) {
// Make a GWT AST.
- types = astBuilder.process(cud, artificialRescues, jsniMethods, jsniRefs);
+ types = astBuilder.process(cud, builder.getSourceMapPath(), artificialRescues,
+ jsniMethods, jsniRefs);
}
for (CompiledClass cc : compiledClasses) {
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompilationUnitBuilder.java b/dev/core/src/com/google/gwt/dev/javac/CompilationUnitBuilder.java
index 1dcd3ea..5d9d481 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompilationUnitBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompilationUnitBuilder.java
@@ -50,6 +50,11 @@
}
@Override
+ public String getSourceMapPath() {
+ return generatedUnit.getSourceMapPath();
+ }
+
+ @Override
public String getTypeName() {
return generatedUnit.getTypeName();
}
@@ -118,6 +123,11 @@
}
@Override
+ public String getSourceMapPath() {
+ return getSourceMapPathFor(resource);
+ }
+
+ @Override
public String getTypeName() {
return typeName;
}
@@ -217,6 +227,13 @@
return new ResourceCompilationUnitBuilder(resource);
}
+ /**
+ * Given a resource, returns the filename that will appear in the source map.
+ */
+ public static String getSourceMapPathFor(Resource resource) {
+ return resource.getPathPrefix() + resource.getPath();
+ }
+
public static String makeContentId(String typeName, String strongHash) {
return typeName + ':' + strongHash;
}
@@ -259,6 +276,9 @@
public abstract ContentId getContentId();
+ /**
+ * Returns the location that should appear in JDT error messages.
+ */
public abstract String getLocation();
public String getSource() {
@@ -268,6 +288,16 @@
return source;
}
+ /**
+ * Returns the location for this resource as it should appear in a sourcemap.
+ * For a regular source file, it should be a path relative to one of the classpath entries
+ * from the ResourceLoader. For generated files, it should be "gen/" followed by the path where
+ * the source file would show up in the generated files directory if the "-gen" compiler option
+ * were enabled.
+ */
+ public abstract String getSourceMapPath();
+
+
public abstract String getTypeName();
public CompilationUnitBuilder setClasses(List<CompiledClass> compiledClasses) {
diff --git a/dev/core/src/com/google/gwt/dev/javac/GeneratedUnit.java b/dev/core/src/com/google/gwt/dev/javac/GeneratedUnit.java
index b16237c..97b347a 100644
--- a/dev/core/src/com/google/gwt/dev/javac/GeneratedUnit.java
+++ b/dev/core/src/com/google/gwt/dev/javac/GeneratedUnit.java
@@ -24,6 +24,14 @@
String getSource();
/**
+ * Returns the path to this resource as it should appear in a source map. This should be a
+ * path that's relative to either an entry in the classpath, or start with some fixed prefix such
+ * as "gen/" for generated files. (It can't be an absolute path because that would make the GWT
+ * compiler output unstable and defeat caching.)
+ */
+ String getSourceMapPath();
+
+ /**
* Returns the source code as a token for {@link DiskCache#INSTANCE}, or -1 if
* the source is not cached.
*/
@@ -33,5 +41,9 @@
String getTypeName();
+ /**
+ * If the generated file was saved to a directory using the -gen option, returns the file's
+ * location on disk. Otherwise null.
+ */
String optionalFileLocation();
}
diff --git a/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java b/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java
index e00e9ba..733a9c7 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java
@@ -56,19 +56,6 @@
*/
public class JsniCollector {
- /**
- * Represents a logical interval of text.
- */
- public static class Interval {
- public final int end;
- public final int start;
-
- public Interval(int start, int end) {
- this.start = start;
- this.end = end;
- }
- }
-
private static final class JsniMethodImpl extends JsniMethod implements
Serializable {
private final JsFunction func;
@@ -152,10 +139,9 @@
}
@Override
- public void collect(CompilationUnitDeclaration cud) {
- cudInfo = correlator.makeSourceInfo(SourceOrigin.create(0, String
- .valueOf(cud.getFileName())));
- super.collect(cud);
+ public void collect(CompilationUnitDeclaration cud, String sourceMapPath) {
+ cudInfo = correlator.makeSourceInfo(SourceOrigin.create(0, sourceMapPath));
+ super.collect(cud, sourceMapPath);
}
@Override
@@ -181,10 +167,11 @@
public static final String JSNI_BLOCK_START = "/*-{";
public static Map<MethodDeclaration, JsniMethod> collectJsniMethods(
- CompilationUnitDeclaration cud, String source, JsScope scope,
+ CompilationUnitDeclaration cud, String sourceMapPath,
+ String source, JsScope scope,
CorrelationFactory correlator) {
Map<MethodDeclaration, JsniMethod> jsniMethods = new IdentityHashMap<MethodDeclaration, JsniMethod>();
- new Visitor(source, scope, correlator, jsniMethods).collect(cud);
+ new Visitor(source, scope, correlator, jsniMethods).collect(cud, sourceMapPath);
return IdentityMaps.normalizeUnmodifiable(jsniMethods);
}
diff --git a/dev/core/src/com/google/gwt/dev/javac/MethodParamCollector.java b/dev/core/src/com/google/gwt/dev/javac/MethodParamCollector.java
index 901e512..362f660 100644
--- a/dev/core/src/com/google/gwt/dev/javac/MethodParamCollector.java
+++ b/dev/core/src/com/google/gwt/dev/javac/MethodParamCollector.java
@@ -59,13 +59,12 @@
/**
* Returns an unmodifiable MethodArgNamesLookup containing the method argument
* names for the supplied compilation unit.
- *
- * @param cud
+ *
* @return MethodArgNamesLookup instance
*/
- public static MethodArgNamesLookup collect(CompilationUnitDeclaration cud) {
+ public static MethodArgNamesLookup collect(CompilationUnitDeclaration cud, String sourceMapPath) {
MethodArgNamesLookup methodArgs = new MethodArgNamesLookup();
- new Visitor(methodArgs).collect(cud);
+ new Visitor(methodArgs).collect(cud, sourceMapPath);
methodArgs.freeze();
return methodArgs;
}
diff --git a/dev/core/src/com/google/gwt/dev/javac/MethodVisitor.java b/dev/core/src/com/google/gwt/dev/javac/MethodVisitor.java
index 03334a4..cd6dfbb 100644
--- a/dev/core/src/com/google/gwt/dev/javac/MethodVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/javac/MethodVisitor.java
@@ -51,10 +51,8 @@
/**
* Collect data about interesting methods in one compilation unit.
- *
- * @param cud
*/
- public void collect(final CompilationUnitDeclaration cud) {
+ public void collect(final CompilationUnitDeclaration cud, String sourceMapPath) {
cud.traverse(new SafeASTVisitor() {
@Override
public void endVisit(TypeDeclaration type, ClassScope scope) {
diff --git a/dev/core/src/com/google/gwt/dev/javac/SourceFileCompilationUnit.java b/dev/core/src/com/google/gwt/dev/javac/SourceFileCompilationUnit.java
index a97407f..311ed5d 100644
--- a/dev/core/src/com/google/gwt/dev/javac/SourceFileCompilationUnit.java
+++ b/dev/core/src/com/google/gwt/dev/javac/SourceFileCompilationUnit.java
@@ -24,7 +24,7 @@
import java.util.List;
/**
- * A compilation unit that was generated.
+ * A compilation unit that was created from a source file in the ResourceLoader's classpath.
*/
class SourceFileCompilationUnit extends CompilationUnitImpl {
diff --git a/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java b/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
index 4a879c0..5dde0d5 100644
--- a/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
+++ b/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
@@ -128,6 +128,11 @@
}
@Override
+ public String getSourceMapPath() {
+ return "gen/" + getTypeName().replace('.', '/') + ".java";
+ }
+
+ @Override
public long getSourceToken() {
if (sw != null) {
throw new IllegalStateException("source not committed");
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
index 1a8410c..30102bc 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
@@ -2901,12 +2901,25 @@
private List<JDeclaredType> newTypes;
- public List<JDeclaredType> process(CompilationUnitDeclaration cud,
+ private String sourceMapPath;
+
+ /**
+ * Builds all the GWT AST nodes that correspond to one Java source file.
+ *
+ * @param cud The compiled form of the Java source from the JDT.
+ * @param sourceMapPath the path that should be included in a sourcemap.
+ * @param artificialRescues Used to decorate the AST.
+ * @param jsniMethods Native methods to add to the AST.
+ * @param jsniRefs Map from JSNI references to their JDT definitions.
+ * @return All the types seen in this source file.
+ */
+ public List<JDeclaredType> process(CompilationUnitDeclaration cud, String sourceMapPath,
Map<TypeDeclaration, Binding[]> artificialRescues,
Map<MethodDeclaration, JsniMethod> jsniMethods, Map<String, Binding> jsniRefs) {
if (cud.types == null) {
return Collections.emptyList();
}
+ this.sourceMapPath = sourceMapPath;
this.artificialRescues = artificialRescues;
this.jsniRefs = jsniRefs;
this.jsniMethods = jsniMethods;
@@ -2954,14 +2967,14 @@
int startLine =
Util.getLineNumber(x.sourceStart, curCud.separatorPositions, 0,
curCud.separatorPositions.length - 1);
- return SourceOrigin.create(x.sourceStart, x.bodyEnd, startLine, curCud.fileName);
+ return SourceOrigin.create(x.sourceStart, x.bodyEnd, startLine, sourceMapPath);
}
SourceInfo makeSourceInfo(ASTNode x) {
int startLine =
Util.getLineNumber(x.sourceStart, curCud.separatorPositions, 0,
curCud.separatorPositions.length - 1);
- return SourceOrigin.create(x.sourceStart, x.sourceEnd, startLine, curCud.fileName);
+ return SourceOrigin.create(x.sourceStart, x.sourceEnd, startLine, sourceMapPath);
}
InternalCompilerException translateException(ASTNode node, Throwable e) {
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 8e90c2c..b83af47 100644
--- a/dev/core/src/com/google/gwt/dev/js/JsReportGenerationVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/js/JsReportGenerationVisitor.java
@@ -18,8 +18,6 @@
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;
@@ -62,9 +60,8 @@
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);
+ SourceInfo target = ((HasSourceInfo) node).getSourceInfo();
+ sourceInfoMap.put(javaScriptRange, target);
return toReturn;
}
@@ -88,39 +85,4 @@
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/test/com/google/gwt/dev/javac/CompilationStateTestBase.java b/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
index 0bc1d59..e8034bd 100644
--- a/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
+++ b/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
@@ -66,6 +66,10 @@
return sourceFile.getString();
}
+ public String getSourceMapPath() {
+ return getTypeName().replace(".", "/") + ".java";
+ }
+
public long getSourceToken() {
return -1;
}
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/AdditionalTypeProviderDelegateTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/AdditionalTypeProviderDelegateTest.java
index 1962d88..1207473 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/AdditionalTypeProviderDelegateTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/AdditionalTypeProviderDelegateTest.java
@@ -37,9 +37,7 @@
private final long createTime = System.currentTimeMillis();
public String optionalFileLocation() {
- // The named file location requires a non-Java extension,
- // or else the file won't get compiled correctly.
- return "myPackage/InsertedClass.notjava";
+ return null; // not used
}
public String getStrongHash() {
@@ -60,11 +58,17 @@
"}";
return classSource;
}
+
+ @Override
+ public String getSourceMapPath() {
+ // The named file location requires a non-Java extension,
+ // or else the file won't get compiled correctly.
+ return "myPackage/InsertedClass.notjava";
+ }
public String getTypeName() {
return "myPackage.InsertedClass";
}
-
public long getSourceToken() {
return -1;
}
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncsErrorMessagesTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncsErrorMessagesTest.java
index f8f9808..68044bc 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncsErrorMessagesTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncsErrorMessagesTest.java
@@ -53,8 +53,8 @@
addSnippetImport("test.SplitPoint3");
expectError("Line 8: Multiple runAsync calls are named test.SplitPoint1");
- expectError("One call is at '/mock/test/SplitPoint1.java:5'");
- expectError("One call is at '/mock/test/SplitPoint3.java:5'");
+ expectError("One call is at 'test/SplitPoint1.java:5'");
+ expectError("One call is at 'test/SplitPoint3.java:5'");
testSnippet("RunAsyncCode.runAsyncCode(SplitPoint1.class);");
}
@@ -111,7 +111,7 @@
private void initializeTestLoggerBuilder() {
testLoggerBuilder = new UnitTestTreeLogger.Builder();
testLoggerBuilder.setLowestLogLevel(TreeLogger.ERROR);
- expectError("Errors in '/mock/test/EntryPoint.java'");
+ expectError("Errors in 'test/EntryPoint.java'");
}
private void testSnippet(String codeSnippet) {
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/RunAsyncNameTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/RunAsyncNameTest.java
index 77de550..9cf7e9c 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/RunAsyncNameTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/RunAsyncNameTest.java
@@ -59,7 +59,7 @@
{
UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder();
builder.setLowestLogLevel(TreeLogger.ERROR);
- builder.expectError("Errors in '/mock/test/EntryPoint.java'", null);
+ builder.expectError("Errors in 'test/EntryPoint.java'", null);
builder.expectError(
"Line 5: Only class literals may be used to name a call to GWT.runAsync()", null);
logger = builder.createLogger();