Author: b...@google.com Date: Fri Mar 13 08:31:38 2009 New Revision: 5010 Added: trunk/dev/core/src/com/google/gwt/core/ext/linker/SymbolData.java (contents, props changed) trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardSymbolData.java (contents, props changed) Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/CompilationResult.java trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationResult.java trunk/dev/core/src/com/google/gwt/core/linker/SymbolMapsLinker.java trunk/dev/core/src/com/google/gwt/dev/PermutationResult.java trunk/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
Log: Expand the amount of data exported by the symbol maps. Patch by: bobv Review by: jat Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/CompilationResult.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/core/ext/linker/CompilationResult.java (original) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/CompilationResult.java Fri Mar 13 08:31:38 2009 @@ -56,12 +56,12 @@ public abstract String getStrongName(); /** - * Returns a map of obfuscated symbol names in the compilation to JSNI-style - * identifiers. This data can allow for on-the-fly deobfuscation of stack + * Returns a map of obfuscated symbol names in the compilation to metadata + * about the symbol. This data can allow for on-the-fly deobfuscation of stack * trace information or to allow server components to have in-depth knowledge * of the runtime structure of compiled objects. */ - public abstract SortedMap<String, String> getSymbolMap(); + public abstract SortedMap<SymbolData, String> getSymbolMap(); @Override public final int hashCode() { Added: trunk/dev/core/src/com/google/gwt/core/ext/linker/SymbolData.java ============================================================================== --- (empty file) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/SymbolData.java Fri Mar 13 08:31:38 2009 @@ -0,0 +1,94 @@ +/* + * Copyright 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.core.ext.linker; + +import java.io.Serializable; +import java.net.URI; +import java.util.Comparator; + +/** + * Provides basic information about symbols in the generated JavaScript. + * + * @see CompilationResult#getSymbolMap() + */ +public interface SymbolData extends Serializable { + /* + * NB: This class is intended to provide enough data to synthesize + * StackTraceElements, however we don't want to use STE in our API in the case + * that we want to provide additional data in the future. + * + * Note also that this class does not provide the name of the symbol it is + * describing, mainly because the JS compilation process results in multiple + * symbols that are mapped onto the same SymbolData (e.g. MakeCallsStatic). + */ + + /** + * A Comparator for use when presenting the data to humans. This Comparator + * orders SymbolData objects by their class names or JSNI idents. + */ + class ClassIdentComparator implements Comparator<SymbolData>, Serializable { + public int compare(SymbolData o1, SymbolData o2) { + String s1 = o1.isClass() ? o1.getClassName() : o1.getJsniIdent(); + String s2 = o2.isClass() ? o2.getClassName() : o2.getJsniIdent(); + return s1.compareTo(s2); + } + } + + /** + * Returns the name of the type or enclosing type if the symbol is a method or + * field. + */ + String getClassName(); + + /** + * Returns a JSNI-like identifier for the symbol if it a method or field, + * otherwise <code>null</code>. + */ + String getJsniIdent(); + + /** + * Returns the name of the member if the symbol is a method or field. + */ + String getMemberName(); + + /** + * Returns the line number on which the symbol was originally declared or + * <code>-1</code> if the line number is unknown. + */ + int getSourceLine(); + + /** + * Returns a URI representing the location of the source. This method will + * return <code>null</code> if the symbol was derived from a transient or + * unknown source. + */ + URI getSourceUri(); + + /** + * Returns <code>true</code> if the symbol represents a class. + */ + boolean isClass(); + + /** + * Returns <code>true</code> if the symbol represents a field. + */ + boolean isField(); + + /** + * Returns <code>true</code> if the symbol represents a method. + */ + boolean isMethod(); +} Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationResult.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationResult.java (original) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationResult.java Fri Mar 13 08:31:38 2009 @@ -19,6 +19,7 @@ import com.google.gwt.core.ext.UnableToCompleteException; import com.google.gwt.core.ext.linker.CompilationResult; import com.google.gwt.core.ext.linker.SelectionProperty; +import com.google.gwt.core.ext.linker.SymbolData; import com.google.gwt.dev.PermutationResult; import com.google.gwt.dev.util.FileBackedObject; @@ -74,7 +75,7 @@ private final FileBackedObject<PermutationResult> resultFile; - private transient SoftReference<SortedMap<String, String>> symbolMap; + private transient SoftReference<SortedMap<SymbolData, String>> symbolMap; private final SortedSet<SortedMap<SelectionProperty, String>> propertyValues = new TreeSet<SortedMap<SelectionProperty, String>>( MAP_COMPARATOR); @@ -126,8 +127,8 @@ } @Override - public SortedMap<String, String> getSymbolMap() { - SortedMap<String, String> toReturn = null; + public SortedMap<SymbolData, String> getSymbolMap() { + SortedMap<SymbolData, String> toReturn = null; if (symbolMap != null) { toReturn = symbolMap.get(); } @@ -135,7 +136,7 @@ if (toReturn == null) { PermutationResult result = loadPermutationResult(); toReturn = result.getSymbolMap(); - symbolMap = new SoftReference<SortedMap<String, String>>(toReturn); + symbolMap = new SoftReference<SortedMap<SymbolData, String>>(toReturn); } return toReturn; Added: trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardSymbolData.java ============================================================================== --- (empty file) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardSymbolData.java Fri Mar 13 08:31:38 2009 @@ -0,0 +1,110 @@ +/* + * Copyright 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.core.ext.linker.impl; + +import com.google.gwt.core.ext.linker.SymbolData; + +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * An immutable implementation of SymbolData. + */ +public class StandardSymbolData implements SymbolData { + + public static SymbolData forClass(String className, String fileName, + int lineNumber) { + URI uri = inferUriFromFileName(fileName); + return new StandardSymbolData(className, null, null, uri, lineNumber); + } + + public static SymbolData forMember(String className, String memberName, + String jsniIdent, String fileName, int lineNumber) { + URI uri = inferUriFromFileName(fileName); + return new StandardSymbolData(className, jsniIdent, memberName, uri, + lineNumber); + } + + private static URI inferUriFromFileName(String fileName) { + File f = new File(fileName); + if (f.exists()) { + return f.toURI(); + } else { + try { + return new URI(fileName); + } catch (URISyntaxException e) { + return null; + } + } + } + + private final String className; + private final String jsniIdent; + private final String memberName; + private final int sourceLine; + private final URI sourceUri; + + private StandardSymbolData(String className, String jsniIdent, + String memberName, URI sourceUri, int sourceLine) { + assert className != null && className.length() > 0 : "className"; + assert !(jsniIdent == null ^ memberName == null) : "jsniIdent ^ memberName"; + assert sourceLine >= -1 : "sourceLine: " + sourceLine; + + this.className = className; + this.jsniIdent = jsniIdent; + this.memberName = memberName; + this.sourceUri = sourceUri; + this.sourceLine = sourceLine; + } + + public String getClassName() { + return className; + } + + public String getJsniIdent() { + return jsniIdent; + } + + public String getMemberName() { + return memberName; + } + + public int getSourceLine() { + return sourceLine; + } + + public URI getSourceUri() { + return sourceUri; + } + + public boolean isClass() { + return memberName == null; + } + + public boolean isField() { + return jsniIdent != null && !jsniIdent.contains("("); + } + + public boolean isMethod() { + return jsniIdent != null && jsniIdent.contains("("); + } + + @Override + public String toString() { + return jsniIdent != null ? jsniIdent : className; + } +} Modified: trunk/dev/core/src/com/google/gwt/core/linker/SymbolMapsLinker.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/core/linker/SymbolMapsLinker.java (original) +++ trunk/dev/core/src/com/google/gwt/core/linker/SymbolMapsLinker.java Fri Mar 13 08:31:38 2009 @@ -24,10 +24,12 @@ import com.google.gwt.core.ext.linker.EmittedArtifact; import com.google.gwt.core.ext.linker.LinkerOrder; import com.google.gwt.core.ext.linker.SelectionProperty; +import com.google.gwt.core.ext.linker.SymbolData; import com.google.gwt.core.ext.linker.LinkerOrder.Order; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; +import java.net.URI; import java.util.Map; import java.util.SortedMap; @@ -44,7 +46,7 @@ * This value is appended to the strong name of the CompilationResult to form * the symbol map's filename. */ - public static final String STRONG_NAME_SUFFIX = "_symbolMap.properties"; + public static final String STRONG_NAME_SUFFIX = ".symbolMap"; @Override public String getDescription() { @@ -107,12 +109,32 @@ pw.println(" }"); } - for (Map.Entry<String, String> entry : result.getSymbolMap().entrySet()) { - // Don't use an actual Properties object because it emits a timestamp - pw.print(entry.getKey()); - pw.print(" = "); + pw.println("# jsName, jsniIdent, className, memberName, sourceUri, sourceLine"); + for (Map.Entry<SymbolData, String> entry : result.getSymbolMap().entrySet()) { + SymbolData symbol = entry.getKey(); + pw.print(entry.getValue()); + + print(pw, symbol.getJsniIdent()); + print(pw, symbol.getClassName()); + print(pw, symbol.getMemberName()); + print(pw, symbol.getSourceUri()); + print(pw, String.valueOf(symbol.getSourceLine())); pw.println(); + } + } + + private void print(PrintWriter pw, String value) { + pw.print(","); + if (value != null) { + pw.print(value); + } + } + + private void print(PrintWriter pw, URI uri) { + pw.print(","); + if (uri != null) { + pw.print(uri.toASCIIString()); } } } Modified: trunk/dev/core/src/com/google/gwt/dev/PermutationResult.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/dev/PermutationResult.java (original) +++ trunk/dev/core/src/com/google/gwt/dev/PermutationResult.java Fri Mar 13 08:31:38 2009 @@ -16,6 +16,7 @@ package com.google.gwt.dev; import com.google.gwt.core.ext.linker.ArtifactSet; +import com.google.gwt.core.ext.linker.SymbolData; import java.io.Serializable; import java.util.SortedMap; @@ -38,5 +39,5 @@ /** * The symbol map for the permutation. */ - SortedMap<String, String> getSymbolMap(); + SortedMap<SymbolData, String> getSymbolMap(); } Modified: trunk/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java (original) +++ trunk/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java Fri Mar 13 08:31:38 2009 @@ -18,6 +18,7 @@ import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.UnableToCompleteException; import com.google.gwt.core.ext.linker.ArtifactSet; +import com.google.gwt.core.ext.linker.SymbolData; import com.google.gwt.core.ext.linker.impl.StandardCompilationAnalysis; import com.google.gwt.core.ext.soyc.Range; import com.google.gwt.core.ext.soyc.SplitPointRecorder; @@ -120,10 +121,10 @@ private static class PermutationResultImpl implements PermutationResult { private final ArtifactSet artifacts = new ArtifactSet(); private final String[] js; - private final SortedMap<String, String> symbolMap; + private final SortedMap<SymbolData, String> symbolMap; public PermutationResultImpl(String[] js, - SortedMap<String, String> symbolMap) { + SortedMap<SymbolData, String> symbolMap) { this.js = js; this.symbolMap = symbolMap; } @@ -136,7 +137,7 @@ return js; } - public SortedMap<String, String> getSymbolMap() { + public SortedMap<SymbolData, String> getSymbolMap() { return symbolMap; } } @@ -167,7 +168,8 @@ JProgram jprogram = ast.getJProgram(); JsProgram jsProgram = ast.getJsProgram(); JJSOptions options = unifiedAst.getOptions(); - Map<String, JsName> symbolTable = new HashMap<String, JsName>(); + Map<SymbolData, JsName> symbolTable = new TreeMap<SymbolData, JsName>( + new SymbolData.ClassIdentComparator()); ResolveRebinds.exec(jprogram, rebindAnswers); @@ -278,7 +280,7 @@ } } - SortedMap<String, String> symbolMap = makeSymbolMap(symbolTable); + SortedMap<SymbolData, String> symbolMap = makeSymbolMap(symbolTable); PermutationResult toReturn = new PermutationResultImpl(js, symbolMap); if (sourceInfoMaps != null) { @@ -788,12 +790,15 @@ return amp.makeStatement(); } - private static SortedMap<String, String> makeSymbolMap( - Map<String, JsName> symbolTable) { + private static SortedMap<SymbolData, String> makeSymbolMap( + Map<SymbolData, JsName> symbolTable) { - SortedMap<String, String> toReturn = new TreeMap<String, String>(); + SortedMap<SymbolData, String> toReturn = new TreeMap<SymbolData, String>( + new SymbolData.ClassIdentComparator()); - for (Map.Entry<String, JsName> entry : symbolTable.entrySet()) { + for (Map.Entry<SymbolData, JsName> entry : symbolTable.entrySet()) { + assert !toReturn.containsKey(entry.getKey()) : "Duplicate key for " + + entry.getKey().toString(); toReturn.put(entry.getKey(), entry.getValue().getShortIdent()); } Modified: trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java (original) +++ trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java Fri Mar 13 08:31:38 2009 @@ -15,7 +15,10 @@ */ package com.google.gwt.dev.jjs.impl; +import com.google.gwt.core.ext.linker.SymbolData; +import com.google.gwt.core.ext.linker.impl.StandardSymbolData; import com.google.gwt.dev.jjs.Correlation; +import com.google.gwt.dev.jjs.HasSourceInfo; import com.google.gwt.dev.jjs.InternalCompilerException; import com.google.gwt.dev.jjs.JsOutputOption; import com.google.gwt.dev.jjs.SourceInfo; @@ -373,12 +376,14 @@ } private void recordSymbol(JReferenceType x, JsName jsName) { - assert !symbolTable.containsKey(x.getName()); - symbolTable.put(x.getName(), jsName); + SymbolData symbolData = StandardSymbolData.forClass(x.getName(), + x.getSourceInfo().getFileName(), x.getSourceInfo().getStartLine()); + assert !symbolTable.containsKey(symbolData); + symbolTable.put(symbolData, jsName); } - private <T extends HasEnclosingType & HasName> void recordSymbol(T x, - JsName jsName) { + private <T extends HasEnclosingType & HasName & HasSourceInfo> void recordSymbol( + T x, JsName jsName) { StringBuilder sb = new StringBuilder(); sb.append(x.getEnclosingType().getName()); sb.append("::"); @@ -405,10 +410,13 @@ sb.append(')'); } - assert !symbolTable.containsKey(sb.toString()) : "Duplicate symbol " + SymbolData symbolData = StandardSymbolData.forMember( + x.getEnclosingType().getName(), x.getName(), sb.toString(), + x.getSourceInfo().getFileName(), x.getSourceInfo().getStartLine()); + assert !symbolTable.containsKey(symbolData) : "Duplicate symbol " + "recorded " + jsName.getIdent() + " for " + x.getName() + " and key " + sb.toString(); - symbolTable.put(sb.toString(), jsName); + symbolTable.put(symbolData, jsName); } } @@ -1796,7 +1804,7 @@ } public static JavaToJavaScriptMap exec(JProgram program, JsProgram jsProgram, - JsOutputOption output, Map<String, JsName> symbolTable) { + JsOutputOption output, Map<SymbolData, JsName> symbolTable) { GenerateJavaScriptAST generateJavaScriptAST = new GenerateJavaScriptAST( program, jsProgram, output, symbolTable); return generateJavaScriptAST.execImpl(); @@ -1870,10 +1878,10 @@ /** * Maps JsNames to machine-usable identifiers. */ - private final Map<String, JsName> symbolTable; + private final Map<SymbolData, JsName> symbolTable; private GenerateJavaScriptAST(JProgram program, JsProgram jsProgram, - JsOutputOption output, Map<String, JsName> symbolTable) { + JsOutputOption output, Map<SymbolData, JsName> symbolTable) { this.program = program; typeOracle = program.typeOracle; this.jsProgram = jsProgram; --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---