Adds dependency information to SOYC reports, so it is clear why
methods that are in the initial download are included there.
This is a merge from /changes/spoon/soyc-withdeps .
Patch by: kprobst
Review by: spoon
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5006 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/CompilationAnalysis.java b/dev/core/src/com/google/gwt/core/ext/linker/CompilationAnalysis.java
index fc7b985..3ee4d18 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/CompilationAnalysis.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/CompilationAnalysis.java
@@ -16,99 +16,87 @@
package com.google.gwt.core.ext.linker;
import com.google.gwt.core.ext.Linker;
-import com.google.gwt.core.ext.soyc.ClassMember;
-import com.google.gwt.core.ext.soyc.FunctionMember;
import com.google.gwt.core.ext.soyc.Range;
import com.google.gwt.core.ext.soyc.Story;
-
-import java.util.Map;
-import java.util.SortedSet;
+import java.io.File;
/**
* Represents analysis data for a CompilationResult.
*/
public abstract class CompilationAnalysis extends Artifact<CompilationAnalysis> {
- /**
- * Associates a Story and a Range of the output. Instances of this interface
- * are obtained from {@link CompilationAnalysis#getSnippets()}.
- */
- public interface Snippet {
- Range getRange();
-
- Story getStory();
- }
-
protected CompilationAnalysis(Class<? extends Linker> linkerType) {
super(linkerType);
}
/**
- * Returns all ClassMembers present in the CompilationResult. This method
- * would typically be used by consumers that are interested in the type
- * hierarchy of the compilation.
+ * @return a file of dependencies
*/
- public abstract SortedSet<ClassMember> getClasses();
+ public abstract File getDepFile();
/**
- * Returns the CompilationResult upon which the analysis was performed.
+ * @return a file of stories
*/
- public abstract CompilationResult getCompilationResult();
+ public abstract File getStoriesFile();
/**
- * Returns all JavaScript FunctionMembers in the output.
+ * @return a file of split points
*/
- public abstract SortedSet<FunctionMember> getFunctions();
-
- /**
- * Provides access to the assignments of Stories to Ranges for a fragment of
- * the output. The Ranges are guaranteed not to overlap, and may be used for
- * exact accounting of bytes. Due to the potential for very large data-sets to
- * be accessible through this method, it is recommended that Snippets should
- * be processed in an incremental fashion that does not require all instances
- * to be retained at once.
- */
- /*
- * NB: The reason that this returns an Iterable, and not a Map, is that we
- * want to delay the construction of Range objects for as long as possible. If
- * we were to return a Map for an analysis of N stories, we would also need N
- * Ranges, plus the overhead of constructing an ordered Map.
- */
- public abstract Iterable<Snippet> getSnippets(int fragmentNumber);
-
- /**
- * Returns splitPointMap.
- */
- public abstract Map<Integer, String> getSplitPointMap();
-
- /**
- * Returns all Stories.
- */
- public abstract SortedSet<Story> getStories();
-
- @Override
- public final int hashCode() {
- // NB: Identity is keyed to the CompilationResult
- return getCompilationResult().hashCode();
- }
-
- @Override
- public String toString() {
- return "Compilation analysis for " + getCompilationResult().toString();
- }
+ public abstract File getSplitPointsFile();
@Override
protected final int compareToComparableArtifact(CompilationAnalysis o) {
- /*
- * The identity of a CompilationAnalysis is based on the identity of its
- * associated CompilationResult.
- */
- return getCompilationResult().compareToComparableArtifact(
- o.getCompilationResult());
+
+ if ((getDepFile() == null)&&(o.getDepFile()==null)){
+ return 0;
+ }
+ else if ((getDepFile() == null)&&(o.getDepFile() != null)){
+ return 1;
+ }
+ else if ((getDepFile() != null)&&(o.getDepFile() == null)){
+ return -1;
+ }
+ else if (getDepFile().getName().compareTo(o.getDepFile().getName()) == 0){
+ if ((getStoriesFile() == null)&&(o.getStoriesFile() == null)){
+ return 0;
+ }
+ else if ((getStoriesFile() == null)&&(o.getStoriesFile() != null)){
+ return 1;
+ }
+ else if ((getStoriesFile() != null)&&(o.getStoriesFile() == null)){
+ return -1;
+ }
+ else if (getStoriesFile().getName().compareTo(o.getStoriesFile().getName()) == 0){
+ if ((getSplitPointsFile() == null)&&(o.getSplitPointsFile() == null)){
+ return 0;
+ }
+ if ((getSplitPointsFile() == null)&&(o.getSplitPointsFile() != null)){
+ return 1;
+ }
+ else if ((getSplitPointsFile() != null)&&(o.getSplitPointsFile() == null)){
+ return -1;
+ }
+ else return getSplitPointsFile().getName().compareTo(o.getSplitPointsFile().getName());
+ }
+ else{
+ return getStoriesFile().getName().compareTo(o.getStoriesFile().getName());
+ }
+ }
+ else return getDepFile().getName().compareTo(o.getDepFile().getName());
}
@Override
protected final Class<CompilationAnalysis> getComparableArtifactType() {
return CompilationAnalysis.class;
}
+
+ @Override
+ public final int hashCode() {
+
+ assert(getDepFile() != null);
+ assert(getStoriesFile() != null);
+ assert(getSplitPointsFile() != null);
+
+ return 17 * (37 + getDepFile().getName().hashCode()) + (37 + getStoriesFile().getName().hashCode()) + (37 + getSplitPointsFile().getName().hashCode());
+ }
}
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationAnalysis.java b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationAnalysis.java
index 522094a..45ff2f6 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationAnalysis.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationAnalysis.java
@@ -18,45 +18,7 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.CompilationAnalysis;
-import com.google.gwt.core.ext.linker.CompilationResult;
-import com.google.gwt.core.ext.soyc.ClassMember;
-import com.google.gwt.core.ext.soyc.FunctionMember;
-import com.google.gwt.core.ext.soyc.Member;
-import com.google.gwt.core.ext.soyc.Range;
-import com.google.gwt.core.ext.soyc.Story;
-import com.google.gwt.core.ext.soyc.Story.Origin;
-import com.google.gwt.core.ext.soyc.impl.AbstractMemberWithDependencies;
-import com.google.gwt.core.ext.soyc.impl.MemberFactory;
-import com.google.gwt.core.ext.soyc.impl.OriginImpl;
-import com.google.gwt.core.ext.soyc.impl.SnippetIterator;
-import com.google.gwt.core.ext.soyc.impl.StandardClassMember;
-import com.google.gwt.core.ext.soyc.impl.StandardFieldMember;
-import com.google.gwt.core.ext.soyc.impl.StandardFunctionMember;
-import com.google.gwt.core.ext.soyc.impl.StandardMethodMember;
-import com.google.gwt.core.ext.soyc.impl.StoryImpl;
-import com.google.gwt.dev.jjs.Correlation;
-import com.google.gwt.dev.jjs.SourceInfo;
-import com.google.gwt.dev.jjs.Correlation.Axis;
-import com.google.gwt.dev.jjs.ast.JField;
-import com.google.gwt.dev.jjs.ast.JMethod;
-import com.google.gwt.dev.jjs.ast.JReferenceType;
-import com.google.gwt.dev.js.ast.JsFunction;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.Stack;
-import java.util.TreeMap;
-import java.util.TreeSet;
+import java.io.File;
/**
* An implementation of CompilationAnalysis. This class transforms SourceInfos
@@ -64,371 +26,50 @@
* API.
*/
public class StandardCompilationAnalysis extends CompilationAnalysis {
- /**
- * A roll-up struct for all the data produced by the analysis to make
- * serialization simpler.
- */
- private static class Data implements Serializable {
- SortedSet<ClassMember> classes;
- SortedSet<FunctionMember> functions;
-
- /**
- * These are the Stories in the order in which they should be presented to
- * the user via {@link CompilationAnalysis#getSnippets()}.
- */
- Map<Integer, List<StoryImpl>> orderedStories = new HashMap<Integer, List<StoryImpl>>();
-
- SortedSet<Story> stories;
- }
/**
- * Associates a SourceInfo with a Range.
+ * File containing method-level control-flow dependencies (corresponding to the current report)
*/
- private static class RangeInfo {
- public final SourceInfo info;
- public final Range range;
-
- public RangeInfo(Range range, SourceInfo info) {
- this.range = range;
- this.info = info;
- }
- }
-
- private Data data;
-
+ private File depFile;
+
/**
- * Used by {@link #popAndRecord(Stack)} to determine start and end ranges.
+ * File containing stories
*/
- private int lastEnd = 0;
-
- private CompilationResult result;
-
+ private File storiesFile;
+
/**
- * This is a class field for convenience, but it should be deleted at the end
- * of the constructor.
+ * File containing split points
*/
- private transient Map<SourceInfo, StoryImpl> storyCache = new IdentityHashMap<SourceInfo, StoryImpl>();
-
- /**
- * This is a class field for convenience, but it should be deleted at the end
- * of the constructor.
- */
- private transient Map<Correlation, Member> membersByCorrelation = new IdentityHashMap<Correlation, Member>();
-
- /**
- * Map from split point numbers to the method where they were set.
- */
- private Map<Integer, String> splitPointMap = new TreeMap<Integer, String>();
+ private File splitPointsFile;
/**
* Constructed by PermutationCompiler.
*/
- public StandardCompilationAnalysis(TreeLogger logger,
- List<Map<Range, SourceInfo>> sourceInfoMaps,
- Map<Integer, String> splitPointMap)
+ public StandardCompilationAnalysis(TreeLogger logger, File depFile, File storiesFile, File splitPointsFile)
throws UnableToCompleteException {
super(StandardLinkerContext.class);
logger = logger.branch(TreeLogger.INFO,
- "Creating CompilationAnalysis (this may take some time)");
-
- data = new Data();
+ "Creating CompilationAnalysis");
- this.splitPointMap = splitPointMap;
-
- /*
- * Don't retain beyond the constructor to avoid lingering references to AST
- * nodes.
- */
- MemberFactory memberFactory = new MemberFactory();
-
- // Record what we've seen so far
- TreeSet<ClassMember> classesMutable = new TreeSet<ClassMember>(
- Member.SOURCE_NAME_COMPARATOR);
- TreeSet<FunctionMember> functionsMutable = new TreeSet<FunctionMember>(
- Member.SOURCE_NAME_COMPARATOR);
- Set<SourceInfo> sourceInfoSeen = new HashSet<SourceInfo>();
-
- int fragment = 0;
- for (Map<Range, SourceInfo> sourceInfoMap : sourceInfoMaps) {
- lastEnd = 0;
- analyzeFragment(memberFactory, classesMutable, functionsMutable,
- sourceInfoMap, sourceInfoSeen, fragment++);
- }
-
- data.classes = Collections.unmodifiableSortedSet(classesMutable);
- data.functions = Collections.unmodifiableSortedSet(functionsMutable);
-
- // Deduplicate the ordered stories into an ordered set
- SortedSet<Story> mutableStories = new TreeSet<Story>(
- StoryImpl.ID_COMPARATOR);
- for (List<StoryImpl> stories : data.orderedStories.values()) {
- mutableStories.addAll(stories);
- }
- data.stories = Collections.unmodifiableSortedSet(mutableStories);
-
- /*
- * Clear the member fields that we don't need anymore to allow GC of the
- * SourceInfo objects
- */
- membersByCorrelation = null;
- storyCache = null;
+ this.depFile = depFile;
+ this.storiesFile = storiesFile;
+ this.splitPointsFile = splitPointsFile;
logger.log(TreeLogger.INFO, "Done");
}
@Override
- public SortedSet<ClassMember> getClasses() {
- return data.classes;
+ public File getDepFile() {
+ return depFile;
}
@Override
- public CompilationResult getCompilationResult() {
- return result;
+ public File getStoriesFile() {
+ return storiesFile;
}
@Override
- public SortedSet<FunctionMember> getFunctions() {
- return data.functions;
- }
-
- @Override
- public Iterable<Snippet> getSnippets(int fragment) {
- final List<StoryImpl> stories = data.orderedStories.get(fragment);
- if (stories == null) {
- throw new IllegalArgumentException("Unknown fragment id " + fragment);
- }
-
- return new Iterable<Snippet>() {
- public Iterator<Snippet> iterator() {
- return new SnippetIterator(stories);
- }
- };
- }
-
- @Override
- public Map<Integer, String> getSplitPointMap() {
- return splitPointMap;
- }
-
- @Override
- public SortedSet<Story> getStories() {
- return data.stories;
- }
-
- /**
- * Back-channel setter used by PermutationCompiler.
- */
- public void setCompilationResult(CompilationResult result) {
- this.result = result;
- }
-
- private void analyzeFragment(MemberFactory memberFactory,
- TreeSet<ClassMember> classesMutable,
- TreeSet<FunctionMember> functionsMutable,
- Map<Range, SourceInfo> sourceInfoMap, Set<SourceInfo> sourceInfoSeen,
- int fragment) {
- /*
- * We want to iterate over the Ranges so that enclosing Ranges come before
- * their enclosed Ranges...
- */
- Range[] dependencyOrder = sourceInfoMap.keySet().toArray(
- new Range[sourceInfoMap.size()]);
- Arrays.sort(dependencyOrder, Range.DEPENDENCY_ORDER_COMPARATOR);
-
- Stack<RangeInfo> dependencyScope = new Stack<RangeInfo>();
- for (Range range : dependencyOrder) {
- SourceInfo info = sourceInfoMap.get(range);
- assert info != null;
-
- // Infer dependency information
- if (!dependencyScope.isEmpty()) {
-
- /*
- * Pop frames until we get back to a container, using this as a chance
- * to build up our list of non-overlapping Ranges to report back to the
- * user.
- */
- while (!dependencyScope.peek().range.contains(range)) {
- popAndRecord(dependencyScope, fragment);
- }
- }
-
- // Possibly create and record Members
- if (!sourceInfoSeen.contains(info)) {
- sourceInfoSeen.add(info);
- for (Correlation c : info.getPrimaryCorrelations()) {
- if (membersByCorrelation.containsKey(c)) {
- continue;
- }
-
- switch (c.getAxis()) {
- case CLASS: {
- JReferenceType type = c.getType();
- StandardClassMember member = memberFactory.get(type);
- membersByCorrelation.put(c, member);
- classesMutable.add(member);
- break;
- }
- case FIELD: {
- JField field = c.getField();
- JReferenceType type = c.getType();
- StandardFieldMember member = memberFactory.get(field);
- memberFactory.get(type).addField(member);
- membersByCorrelation.put(c, member);
- break;
- }
- case FUNCTION: {
- JsFunction function = c.getFunction();
- StandardFunctionMember member = memberFactory.get(function);
- membersByCorrelation.put(c, member);
- functionsMutable.add(member);
- break;
- }
- case METHOD: {
- JMethod method = c.getMethod();
- JReferenceType type = c.getType();
- StandardMethodMember member = memberFactory.get(method);
- memberFactory.get(type).addMethod(member);
- membersByCorrelation.put(c, member);
- break;
- }
- }
- }
- }
-
- /*
- * Record dependencies as observed in the structure of the JS output. This
- * an an ad-hoc approach that just looks at which SourceInfos are used
- * within the Range of another SourceInfo.
- */
- Set<Correlation> correlationsInScope = new HashSet<Correlation>();
- for (RangeInfo outer : dependencyScope) {
- SourceInfo outerInfo = outer.info;
- correlationsInScope.addAll(outerInfo.getPrimaryCorrelations());
-
- for (Correlation outerCorrelation : outerInfo.getPrimaryCorrelations()) {
- Member outerMember = membersByCorrelation.get(outerCorrelation);
-
- if (outerMember instanceof AbstractMemberWithDependencies) {
- for (Correlation innerCorrelation : info.getAllCorrelations()) {
- /*
- * This check prevents an inlined method from depending on the
- * method or function into which is was inlined.
- */
- if (correlationsInScope.contains(innerCorrelation)) {
- continue;
- }
-
- Member innerMember = membersByCorrelation.get(innerCorrelation);
-
- /*
- * The null check is because we may not create Members for all
- * types of Correlations.
- */
- if (innerMember != null) {
- if (((AbstractMemberWithDependencies) outerMember).addDependency(innerMember)) {
- // System.out.println(outerMember + " -> " + innerMember);
- }
- }
- }
- }
- }
- }
-
- dependencyScope.push(new RangeInfo(range, info));
- }
-
- // Unwind the rest of the stack to finish out the ranges
- while (!dependencyScope.isEmpty()) {
- popAndRecord(dependencyScope, fragment);
- }
-
- /*
- * Because the first Range corresponds to the SourceInfo of the whole
- * program, we'll know that we got all of the data if the ends match up. If
- * this assert passes, we know that we've correctly generated a sequence of
- * non-overlapping Ranges that encompass the whole program.
- */
- assert dependencyOrder[0].getEnd() == lastEnd;
- }
-
- /**
- * Remove an element from the RangeInfo stack and stare a new StoryImpl with
- * the right length, possibly sub-dividing the super-enclosing Range in the
- * process.
- */
- private void popAndRecord(Stack<RangeInfo> dependencyScope, int fragment) {
- RangeInfo rangeInfo = dependencyScope.pop();
- Range toStore = rangeInfo.range;
-
- /*
- * Make a new Range for the gap between the popped Range and whatever we
- * last stored.
- */
- if (lastEnd < toStore.getStart()) {
- Range newRange = new Range(lastEnd, toStore.getStart());
- assert !dependencyScope.isEmpty();
-
- SourceInfo gapInfo = dependencyScope.peek().info;
- recordStory(gapInfo, fragment, newRange.length());
- lastEnd += newRange.length();
- }
-
- /*
- * Store as much of the current Range as we haven't previously stored. The
- * Max.max() is there to take care of the tail end of Ranges that have had a
- * sub-range previously stored.
- */
- if (lastEnd < toStore.getEnd()) {
- Range newRange = new Range(Math.max(lastEnd, toStore.getStart()),
- toStore.getEnd());
- recordStory(rangeInfo.info, fragment, newRange.length());
- lastEnd += newRange.length();
- }
- }
-
- private void recordStory(SourceInfo info, int fragment, int length) {
- assert storyCache != null;
-
- StoryImpl theStory;
- if (!storyCache.containsKey(info)) {
-
- SortedSet<Member> members = new TreeSet<Member>(
- Member.TYPE_AND_SOURCE_NAME_COMPARATOR);
-
- if (info != null) {
- for (Correlation c : info.getAllCorrelations()) {
- Member m = membersByCorrelation.get(c);
- if (m != null) {
- members.add(m);
- }
- }
- }
-
- SortedSet<Origin> origins = new TreeSet<Origin>();
- for (Correlation c : info.getAllCorrelations(Axis.ORIGIN)) {
- origins.add(new OriginImpl(c.getOrigin()));
- }
-
- String literalType = null;
- Correlation literalCorrelation = info.getPrimaryCorrelation(Axis.LITERAL);
- if (literalCorrelation != null) {
- literalType = literalCorrelation.getLiteral().getDescription();
- }
-
- theStory = new StoryImpl(storyCache.size(), members, info.getMutations(),
- origins, literalType, fragment, length);
- storyCache.put(info, theStory);
- } else {
- // Use a copy-constructed instance
- theStory = new StoryImpl(storyCache.get(info), length);
- }
-
- List<StoryImpl> stories = data.orderedStories.get(fragment);
- if (stories == null) {
- stories = new ArrayList<StoryImpl>();
- data.orderedStories.put(fragment, stories);
- }
- stories.add(theStory);
+ public File getSplitPointsFile() {
+ return splitPointsFile;
}
}
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java
index 3666044..0980040 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java
@@ -269,7 +269,6 @@
FileBackedObject<PermutationResult> resultFile)
throws UnableToCompleteException {
PermutationResult permutationResult = resultFile.newInstance(logger);
-
String strongName = Util.computeStrongName(Util.getBytes(permutationResult.getJs()));
StandardCompilationResult result = resultsByStrongName.get(strongName);
if (result == null) {
@@ -280,10 +279,6 @@
// Add any other Permutations
ArtifactSet otherArtifacts = permutationResult.getArtifacts();
if (otherArtifacts != null) {
- // Fixups for StandardCompilationAnalysis objects
- for (StandardCompilationAnalysis a : otherArtifacts.find(StandardCompilationAnalysis.class)) {
- a.setCompilationResult(result);
- }
artifacts.addAll(otherArtifacts);
}
}
@@ -461,6 +456,18 @@
outFile.setLastModified(artifact.getLastModified());
}
}
+ for (StandardCompilationAnalysis soycFiles : artifacts.find(StandardCompilationAnalysis.class)){
+ TreeLogger artifactLogger = logger.branch(TreeLogger.DEBUG,
+ "Emitting soyc resources.", null);
+ File depFile = new File(extraPath + "/soycReport", soycFiles.getDepFile().getName());
+ Util.copy(artifactLogger, soycFiles.getDepFile(), depFile);
+
+ File storiesFile = new File(extraPath + "/soycReport", soycFiles.getStoriesFile().getName());
+ Util.copy(artifactLogger, soycFiles.getStoriesFile(), storiesFile);
+
+ File splitPointsFile = new File(extraPath + "/soycReport", soycFiles.getSplitPointsFile().getName());
+ Util.copy(artifactLogger, soycFiles.getSplitPointsFile(), splitPointsFile);
+ }
}
/**
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/SplitPointRecorder.java b/dev/core/src/com/google/gwt/core/ext/soyc/SplitPointRecorder.java
new file mode 100644
index 0000000..7acdd04
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/SplitPointRecorder.java
@@ -0,0 +1,36 @@
+/*
+ * 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.soyc;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.jjs.ast.JProgram;
+
+import java.io.File;
+
+public interface SplitPointRecorder {
+ /**
+ * Used to record (runAsync) split points of a program
+ *
+ * @param jprogram
+ * @param workDir
+ * @param permutationId
+ * @param logger
+ * @return The file that the dependencies are recorded in
+ */
+ public File recordSplitPoints(JProgram jprogram, File workDir, int permutationId, TreeLogger logger);
+
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/Story.java b/dev/core/src/com/google/gwt/core/ext/soyc/Story.java
index a08fd85..7805c26 100644
--- a/dev/core/src/com/google/gwt/core/ext/soyc/Story.java
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/Story.java
@@ -79,13 +79,6 @@
SortedSet<Member> getMembers();
/**
- * Gets a list of transformations applied to the original source code in order
- * to produce the story entry. This method will not return any data unless the
- * compiler has been configured to collect mutation data.
- */
- List<String> getMutations();
-
- /**
* Returns the locations of the Story's source. Identical structures (such as
* string literals) that appear in multiple locations in the source may be
* merged by the compiler into a single Story.
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/StoryRecorder.java b/dev/core/src/com/google/gwt/core/ext/soyc/StoryRecorder.java
new file mode 100644
index 0000000..85737a5
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/StoryRecorder.java
@@ -0,0 +1,40 @@
+/*
+ * 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.soyc;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.jjs.SourceInfo;
+import com.google.gwt.dev.jjs.ast.JProgram;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+public interface StoryRecorder {
+ /**
+ * Used to record dependencies of a program
+ *
+ * @param jprogram
+ * @param workDir
+ * @param permutationId
+ * @param logger
+ * @return The file that the dependencies are recorded in
+ */
+ public File recordStories(JProgram jprogram, File workDir, int permutationId,
+ TreeLogger logger, List<Map<Range, SourceInfo>> sourceInfoMaps,
+ String[] js);
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/impl/DependencyRecorderImpl.java b/dev/core/src/com/google/gwt/core/ext/soyc/impl/DependencyRecorderImpl.java
new file mode 100644
index 0000000..1880947
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/impl/DependencyRecorderImpl.java
@@ -0,0 +1,151 @@
+/*
+ * 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.soyc.impl;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.jjs.ast.JMethod;
+import com.google.gwt.dev.jjs.ast.JProgram;
+import com.google.gwt.dev.jjs.impl.ControlFlowAnalyzer;
+import com.google.gwt.dev.util.HtmlTextOutput;
+import com.google.gwt.util.tools.Utility;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.zip.GZIPOutputStream;
+
+public class DependencyRecorderImpl implements ControlFlowAnalyzer.DependencyRecorder {
+
+ private OutputStreamWriter writer;
+ private PrintWriter pw;
+ private HtmlTextOutput htmlOut;
+
+ /**
+ * Used to record the dependencies of a specific method
+ *
+ * @param liveMethod
+ * @param dependencyChain
+ */
+ public void methodIsLiveBecause(JMethod liveMethod,
+ ArrayList<JMethod> dependencyChain) {
+ printMethodDependency(liveMethod, dependencyChain);
+ }
+
+ /**
+ * Used to record dependencies of a program
+ *
+ * @param jprogram
+ * @param workDir
+ * @param permutationId
+ * @param logger
+ * @return The file that the dependencies are recorded in
+ */
+ public File recordDependencies(JProgram jprogram, File workDir,
+ int permutationId, TreeLogger logger) {
+
+ logger = logger.branch(TreeLogger.INFO, "Creating Dependencies file for SOYC");
+
+ ControlFlowAnalyzer dependencyAnalyzer = new ControlFlowAnalyzer(jprogram);
+ dependencyAnalyzer.setDependencyRecorder(this);
+
+ File appendDepFile = new File(workDir, "dependencies" + permutationId
+ + ".xml.gz");
+ try {
+ FileOutputStream stream = new FileOutputStream(appendDepFile, true);
+ writer = new OutputStreamWriter(new GZIPOutputStream(stream), "UTF-8");
+ appendDepFile.getParentFile().mkdirs();
+ pw = new PrintWriter(writer);
+ htmlOut = new HtmlTextOutput(pw, false);
+ } catch (Throwable e) {
+ logger.log(TreeLogger.ERROR, "Could not open dependency file.", e);
+ }
+
+ printPre();
+ for (JMethod method : jprogram.getAllEntryMethods()) {
+ dependencyAnalyzer.traverseFrom(method);
+ }
+ printPost();
+ pw.close();
+ Utility.close(writer);
+
+ logger.log(TreeLogger.INFO, "Done");
+
+ return appendDepFile;
+ }
+
+ /**
+ * Prints the control-flow dependencies to a file in a specific format
+ *
+ * @param liveMethod
+ * @param dependencyChain
+ */
+ private void printMethodDependency(JMethod liveMethod,
+ ArrayList<JMethod> dependencyChain) {
+ String curLine;
+ for (int i = dependencyChain.size() - 1; i >= 0; i--) {
+ JMethod curMethod = dependencyChain.get(i);
+ String sFullMethodString = curMethod.getName();
+ if (curMethod.getEnclosingType() != null) {
+ sFullMethodString = curMethod.getEnclosingType().getName() + "::"
+ + curMethod.getName();
+ }
+ if (i == dependencyChain.size() - 1) {
+ curLine = "<method name=\"" + sFullMethodString + "\">";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ htmlOut.indentIn();
+ htmlOut.indentIn();
+ } else {
+ curLine = "<called by=\"" + sFullMethodString + "\"/>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ }
+ }
+ htmlOut.indentOut();
+ htmlOut.indentOut();
+ curLine = "</method>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ }
+
+ /**
+ * Prints the preamble necessary for the dependencies file
+ */
+ private void printPre() {
+ String curLine = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ curLine = "<soyc-dependencies>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ htmlOut.indentIn();
+ htmlOut.indentIn();
+ }
+
+ /**
+ * Prints the closing lines necessary for the dependencies file
+ */
+ private void printPost() {
+ String curLine = "</soyc-dependencies>";
+ htmlOut.indentOut();
+ htmlOut.indentOut();
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/impl/SnippetIterator.java b/dev/core/src/com/google/gwt/core/ext/soyc/impl/SnippetIterator.java
deleted file mode 100644
index 7d2fb50..0000000
--- a/dev/core/src/com/google/gwt/core/ext/soyc/impl/SnippetIterator.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2008 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.soyc.impl;
-
-import com.google.gwt.core.ext.linker.CompilationAnalysis.Snippet;
-import com.google.gwt.core.ext.soyc.Range;
-import com.google.gwt.core.ext.soyc.Story;
-
-import java.util.Iterator;
-
-/**
- * Uses a list of StoryImpls present a sequence of Snippets by synthesizing
- * Range objects based on the length of the StoryImpls.
- */
-public class SnippetIterator implements Iterator<Snippet> {
- /**
- * An Iterator over the backing object.
- */
- private final Iterator<StoryImpl> iter;
-
- /**
- * The starting position for the next Range object generated.
- */
- private int start = 0;
-
- public SnippetIterator(Iterable<StoryImpl> stories) {
- iter = stories.iterator();
- }
-
- public boolean hasNext() {
- return iter.hasNext();
- }
-
- public Snippet next() {
- final StoryImpl story = iter.next();
- final Range range = new Range(start, start + story.getLength());
- start += story.getLength();
-
- return new Snippet() {
- public Range getRange() {
- return range;
- }
-
- public Story getStory() {
- return story;
- }
- };
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-}
\ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/impl/SplitPointRecorderImpl.java b/dev/core/src/com/google/gwt/core/ext/soyc/impl/SplitPointRecorderImpl.java
new file mode 100644
index 0000000..de08526
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/impl/SplitPointRecorderImpl.java
@@ -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.soyc.impl;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.soyc.SplitPointRecorder;
+import com.google.gwt.dev.jjs.ast.JProgram;
+import com.google.gwt.dev.util.HtmlTextOutput;
+import com.google.gwt.util.tools.Utility;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Map;
+import java.util.zip.GZIPOutputStream;
+
+public class SplitPointRecorderImpl implements SplitPointRecorder {
+
+ private FileOutputStream stream;
+ private OutputStreamWriter writer;
+ private PrintWriter pw;
+ private HtmlTextOutput htmlOut;
+
+ /**
+ * Used to record (runAsync) split points of a program
+ *
+ * @param jprogram
+ * @param workDir
+ * @param permutationId
+ * @param logger
+ * @return The file that the dependencies are recorded in
+ */
+ public File recordSplitPoints(JProgram jprogram, File workDir,
+ int permutationId, TreeLogger logger) {
+
+ logger = logger.branch(TreeLogger.INFO, "Creating Split Point Map file for SOYC");
+
+ File splitPointsFile = new File(workDir, "splitPoints"
+ + Integer.toString(permutationId) + ".xml.gz");
+ try {
+ stream = new FileOutputStream(splitPointsFile, true);
+ writer = new OutputStreamWriter(new GZIPOutputStream(stream), "UTF-8");
+ splitPointsFile.getParentFile().mkdirs();
+ pw = new PrintWriter(writer);
+ htmlOut = new HtmlTextOutput(pw, false);
+
+ String curLine = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+
+ curLine = "<soyc>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ htmlOut.indentIn();
+ htmlOut.indentIn();
+
+ Map<Integer, String> splitPointMap = jprogram.getSplitPointMap();
+ if (splitPointMap.size() > 0) {
+ curLine = "<splitpoints>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ htmlOut.indentIn();
+ htmlOut.indentIn();
+ for (Integer splitPointCount : splitPointMap.keySet()) {
+ curLine = "<splitpoint id=\"" + splitPointCount + "\" location=\""
+ + splitPointMap.get(splitPointCount) + "\"/>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ }
+ htmlOut.indentOut();
+ htmlOut.indentOut();
+ curLine = "</splitpoints>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ }
+
+ htmlOut.indentOut();
+ htmlOut.indentOut();
+ curLine = "</soyc>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+
+ Utility.close(writer);
+ pw.close();
+
+ logger.log(TreeLogger.INFO, "Done");
+
+ } catch (Throwable e) {
+ logger.log(TreeLogger.ERROR, "Could not open dependency file.", e);
+ }
+
+ return splitPointsFile;
+
+ }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryImpl.java b/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryImpl.java
index 7aab089..6526b3e 100644
--- a/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryImpl.java
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryImpl.java
@@ -17,13 +17,10 @@
import com.google.gwt.core.ext.soyc.Member;
import com.google.gwt.core.ext.soyc.Story;
-import com.google.gwt.dev.jjs.SourceInfo.Mutation;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-import java.util.List;
import java.util.SortedSet;
/**
@@ -46,18 +43,16 @@
private final int length;
private final String literalDescription;
private final SortedSet<Member> members;
- private final List<String> mutations;
private final SortedSet<Origin> origins;
/**
* Standard constructor. This constructor will create unmodifiable versions of
* the collections passed into it.
*/
- public StoryImpl(int id, SortedSet<Member> members, List<Mutation> mutations,
+ public StoryImpl(int id, SortedSet<Member> members,
SortedSet<Origin> origins, String literalDescription, int fragment,
int length) {
assert members != null;
- assert mutations != null;
assert origins != null;
assert fragment >= 0;
assert length > 0;
@@ -69,12 +64,6 @@
this.literalDescription = literalDescription == null ? null
: literalDescription.intern();
this.members = Collections.unmodifiableSortedSet(members);
-
- List<String> mutableMutations = new ArrayList<String>(mutations.size());
- for (Mutation m : mutations) {
- mutableMutations.add(m.getDescription() + " by " + m.getCaller());
- }
- this.mutations = Collections.unmodifiableList(mutableMutations);
this.origins = Collections.unmodifiableSortedSet(origins);
}
@@ -89,7 +78,6 @@
this.length = length;
this.literalDescription = other.literalDescription;
this.members = other.members;
- this.mutations = other.mutations;
this.origins = other.origins;
}
@@ -128,10 +116,6 @@
return members;
}
- public List<String> getMutations() {
- return mutations;
- }
-
public SortedSet<Origin> getSourceOrigin() {
return origins;
}
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryRecorderImpl.java b/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryRecorderImpl.java
new file mode 100644
index 0000000..b861c32
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryRecorderImpl.java
@@ -0,0 +1,485 @@
+/*
+ * 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.soyc.impl;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.soyc.Range;
+import com.google.gwt.core.ext.soyc.Story;
+import com.google.gwt.core.ext.soyc.StoryRecorder;
+import com.google.gwt.dev.jjs.Correlation;
+import com.google.gwt.dev.jjs.SourceInfo;
+import com.google.gwt.dev.jjs.Correlation.Axis;
+import com.google.gwt.dev.jjs.ast.JField;
+import com.google.gwt.dev.jjs.ast.JMethod;
+import com.google.gwt.dev.jjs.ast.JProgram;
+import com.google.gwt.dev.jjs.ast.JReferenceType;
+import com.google.gwt.dev.js.ast.JsFunction;
+import com.google.gwt.dev.util.HtmlTextOutput;
+import com.google.gwt.util.tools.Utility;
+import com.google.gwt.core.ext.soyc.ClassMember;
+import com.google.gwt.core.ext.soyc.FunctionMember;
+import com.google.gwt.core.ext.soyc.Member;
+import com.google.gwt.core.ext.soyc.Story.Origin;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.Stack;
+import java.util.TreeSet;
+import java.util.zip.GZIPOutputStream;
+
+public class StoryRecorderImpl implements StoryRecorder {
+
+ private FileOutputStream stream;
+ private OutputStreamWriter writer;
+ private PrintWriter pw;
+ private HtmlTextOutput htmlOut;
+
+ private Map<Story, Integer> storyIds = new HashMap<Story, Integer>();
+ private String[] js;
+ private int curHighestFragment = 0;
+
+ /**
+ * Used to record dependencies of a program
+ *
+ * @param jprogram
+ * @param workDir
+ * @param permutationId
+ * @param logger
+ * @return The file that the dependencies are recorded in
+ */
+ public File recordStories(JProgram jprogram, File workDir, int permutationId,
+ TreeLogger logger, List<Map<Range, SourceInfo>> sourceInfoMaps,
+ String[] js) {
+
+ logger = logger.branch(TreeLogger.INFO, "Creating Stories file for SOYC");
+
+ this.js = js;
+
+ File storiesFile = new File(workDir, "stories"
+ + Integer.toString(permutationId) + ".xml.gz");
+ try {
+ stream = new FileOutputStream(storiesFile, true);
+ writer = new OutputStreamWriter(new GZIPOutputStream(stream), "UTF-8");
+ storiesFile.getParentFile().mkdirs();
+ pw = new PrintWriter(writer);
+ htmlOut = new HtmlTextOutput(pw, false);
+
+ String curLine = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+
+ curLine = "<soyc>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ htmlOut.indentIn();
+ htmlOut.indentIn();
+
+ curLine = "<stories>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ htmlOut.indentIn();
+ htmlOut.indentIn();
+
+ /*
+ * Don't retain beyond the constructor to avoid lingering references to
+ * AST nodes.
+ */
+ MemberFactory memberFactory = new MemberFactory();
+
+ // Record what we've seen so far
+ TreeSet<ClassMember> classesMutable = new TreeSet<ClassMember>(
+ Member.SOURCE_NAME_COMPARATOR);
+ TreeSet<FunctionMember> functionsMutable = new TreeSet<FunctionMember>(
+ Member.SOURCE_NAME_COMPARATOR);
+ Set<SourceInfo> sourceInfoSeen = new HashSet<SourceInfo>();
+
+ int fragment = 0;
+ for (Map<Range, SourceInfo> sourceInfoMap : sourceInfoMaps) {
+ lastEnd = 0;
+ analyzeFragment(memberFactory, classesMutable, functionsMutable,
+ sourceInfoMap, sourceInfoSeen, fragment++);
+ }
+
+ /*
+ * Clear the member fields that we don't need anymore to allow GC of the
+ * SourceInfo objects
+ */
+ membersByCorrelation = null;
+ storyCache = null;
+
+ htmlOut.indentOut();
+ htmlOut.indentOut();
+ curLine = "</stories>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+
+ htmlOut.indentOut();
+ htmlOut.indentOut();
+ curLine = "</soyc>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+
+ Utility.close(writer);
+ pw.close();
+
+ logger.log(TreeLogger.INFO, "Done");
+
+ } catch (Throwable e) {
+ logger.log(TreeLogger.ERROR, "Could not open dependency file.", e);
+ }
+
+ return storiesFile;
+ }
+
+ /**
+ * Associates a SourceInfo with a Range.
+ */
+ private static class RangeInfo {
+ public final SourceInfo info;
+ public final Range range;
+
+ public RangeInfo(Range range, SourceInfo info) {
+ this.range = range;
+ this.info = info;
+ }
+ }
+
+ /**
+ * Used by {@link #popAndRecord(Stack)} to determine start and end ranges.
+ */
+ private int lastEnd = 0;
+
+ /**
+ * This is a class field for convenience, but it should be deleted at the end
+ * of the constructor.
+ */
+ private transient Map<SourceInfo, StoryImpl> storyCache = new IdentityHashMap<SourceInfo, StoryImpl>();
+
+ /**
+ * This is a class field for convenience, but it should be deleted at the end
+ * of the constructor.
+ */
+ private transient Map<Correlation, Member> membersByCorrelation = new IdentityHashMap<Correlation, Member>();
+
+ private void analyzeFragment(MemberFactory memberFactory,
+ TreeSet<ClassMember> classesMutable,
+ TreeSet<FunctionMember> functionsMutable,
+ Map<Range, SourceInfo> sourceInfoMap, Set<SourceInfo> sourceInfoSeen,
+ int fragment) {
+ /*
+ * We want to iterate over the Ranges so that enclosing Ranges come before
+ * their enclosed Ranges...
+ */
+ Range[] dependencyOrder = sourceInfoMap.keySet().toArray(
+ new Range[sourceInfoMap.size()]);
+ Arrays.sort(dependencyOrder, Range.DEPENDENCY_ORDER_COMPARATOR);
+
+ Stack<RangeInfo> dependencyScope = new Stack<RangeInfo>();
+ for (Range range : dependencyOrder) {
+ SourceInfo info = sourceInfoMap.get(range);
+ assert info != null;
+
+ // Infer dependency information
+ if (!dependencyScope.isEmpty()) {
+
+ /*
+ * Pop frames until we get back to a container, using this as a chance
+ * to build up our list of non-overlapping Ranges to report back to the
+ * user.
+ */
+ while (!dependencyScope.peek().range.contains(range)) {
+ popAndRecord(dependencyScope, fragment);
+ }
+ }
+
+ // Possibly create and record Members
+ if (!sourceInfoSeen.contains(info)) {
+ sourceInfoSeen.add(info);
+ for (Correlation c : info.getPrimaryCorrelations()) {
+ if (membersByCorrelation.containsKey(c)) {
+ continue;
+ }
+
+ switch (c.getAxis()) {
+ case CLASS: {
+ JReferenceType type = c.getType();
+ StandardClassMember member = memberFactory.get(type);
+ membersByCorrelation.put(c, member);
+ classesMutable.add(member);
+ break;
+ }
+ case FIELD: {
+ JField field = c.getField();
+ JReferenceType type = c.getType();
+ StandardFieldMember member = memberFactory.get(field);
+ memberFactory.get(type).addField(member);
+ membersByCorrelation.put(c, member);
+ break;
+ }
+ case FUNCTION: {
+ JsFunction function = c.getFunction();
+ StandardFunctionMember member = memberFactory.get(function);
+ membersByCorrelation.put(c, member);
+ functionsMutable.add(member);
+ break;
+ }
+ case METHOD: {
+ JMethod method = c.getMethod();
+ JReferenceType type = c.getType();
+ StandardMethodMember member = memberFactory.get(method);
+ memberFactory.get(type).addMethod(member);
+ membersByCorrelation.put(c, member);
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * Record dependencies as observed in the structure of the JS output. This
+ * an an ad-hoc approach that just looks at which SourceInfos are used
+ * within the Range of another SourceInfo.
+ */
+ Set<Correlation> correlationsInScope = new HashSet<Correlation>();
+ for (RangeInfo outer : dependencyScope) {
+ SourceInfo outerInfo = outer.info;
+ correlationsInScope.addAll(outerInfo.getPrimaryCorrelations());
+ }
+
+ dependencyScope.push(new RangeInfo(range, info));
+ }
+
+ // Unwind the rest of the stack to finish out the ranges
+ while (!dependencyScope.isEmpty()) {
+ popAndRecord(dependencyScope, fragment);
+ }
+
+ /*
+ * Because the first Range corresponds to the SourceInfo of the whole
+ * program, we'll know that we got all of the data if the ends match up. If
+ * this assert passes, we know that we've correctly generated a sequence of
+ * non-overlapping Ranges that encompass the whole program.
+ */
+ assert dependencyOrder[0].getEnd() == lastEnd;
+ }
+
+ /**
+ * Remove an element from the RangeInfo stack and stare a new StoryImpl with
+ * the right length, possibly sub-dividing the super-enclosing Range in the
+ * process.
+ */
+ private void popAndRecord(Stack<RangeInfo> dependencyScope, int fragment) {
+ RangeInfo rangeInfo = dependencyScope.pop();
+ Range toStore = rangeInfo.range;
+
+ /*
+ * Make a new Range for the gap between the popped Range and whatever we
+ * last stored.
+ */
+ if (lastEnd < toStore.getStart()) {
+ Range newRange = new Range(lastEnd, toStore.getStart());
+ assert !dependencyScope.isEmpty();
+
+ SourceInfo gapInfo = dependencyScope.peek().info;
+ recordStory(gapInfo, fragment, newRange.length(), newRange);
+
+ lastEnd += newRange.length();
+ }
+
+ /*
+ * Store as much of the current Range as we haven't previously stored. The
+ * Max.max() is there to take care of the tail end of Ranges that have had a
+ * sub-range previously stored.
+ */
+ if (lastEnd < toStore.getEnd()) {
+ Range newRange = new Range(Math.max(lastEnd, toStore.getStart()),
+ toStore.getEnd());
+ recordStory(rangeInfo.info, fragment, newRange.length(), newRange);
+ lastEnd += newRange.length();
+ }
+ }
+
+ private void recordStory(SourceInfo info, int fragment, int length,
+ Range range) {
+ assert storyCache != null;
+
+ if (fragment > curHighestFragment) {
+ curHighestFragment = fragment;
+ }
+
+ StoryImpl theStory;
+ if (!storyCache.containsKey(info)) {
+
+ SortedSet<Member> members = new TreeSet<Member>(
+ Member.TYPE_AND_SOURCE_NAME_COMPARATOR);
+
+ if (info != null) {
+ for (Correlation c : info.getAllCorrelations()) {
+ Member m = membersByCorrelation.get(c);
+ if (m != null) {
+ members.add(m);
+ }
+ }
+ }
+
+ SortedSet<Origin> origins = new TreeSet<Origin>();
+ for (Correlation c : info.getAllCorrelations(Axis.ORIGIN)) {
+ origins.add(new OriginImpl(c.getOrigin()));
+ }
+
+ String literalType = null;
+ Correlation literalCorrelation = info.getPrimaryCorrelation(Axis.LITERAL);
+ if (literalCorrelation != null) {
+ literalType = literalCorrelation.getLiteral().getDescription();
+ }
+
+ theStory = new StoryImpl(storyCache.size(), members, origins,
+ literalType, fragment, length);
+ storyCache.put(info, theStory);
+ } else {
+ // Use a copy-constructed instance
+ theStory = new StoryImpl(storyCache.get(info), length);
+ }
+
+ emitStory(theStory, range);
+ }
+
+ private void emitStory(StoryImpl story, Range range) {
+
+ int storyNum;
+ if (storyIds.containsKey(story)) {
+ storyNum = storyIds.get(story);
+ } else {
+ storyNum = storyIds.size();
+ storyIds.put(story, storyNum);
+ }
+
+ String curLine = "<story id=\"story" + Integer.toString(storyNum) + "\"";
+ if (story.getLiteralTypeName() != null) {
+ curLine = curLine + " literal=\"" + story.getLiteralTypeName() + "\"";
+ }
+ curLine = curLine + ">";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+
+ Set<Origin> origins = story.getSourceOrigin();
+ if (origins.size() > 0) {
+ htmlOut.indentIn();
+ htmlOut.indentIn();
+
+ curLine = "<origins>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+
+ htmlOut.indentIn();
+ htmlOut.indentIn();
+ }
+ for (Origin origin : origins) {
+ curLine = "<origin lineNumber=\""
+ + Integer.toString(origin.getLineNumber()) + "\" location=\""
+ + origin.getLocation() + "\"/>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ }
+ if (origins.size() > 0) {
+ htmlOut.indentOut();
+ htmlOut.indentOut();
+
+ curLine = "</origins>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+
+ htmlOut.indentOut();
+ htmlOut.indentOut();
+ }
+
+ Set<Member> correlations = story.getMembers();
+ if (correlations.size() > 0) {
+ htmlOut.indentIn();
+ htmlOut.indentIn();
+
+ curLine = "<correlations>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+
+ htmlOut.indentIn();
+ htmlOut.indentIn();
+ }
+ for (Member correlation : correlations) {
+ curLine = "<by idref=\"" + correlation.getSourceName() + "\"/>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ }
+ if (correlations.size() > 0) {
+ htmlOut.indentOut();
+ htmlOut.indentOut();
+
+ curLine = "</correlations>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+
+ htmlOut.indentOut();
+ htmlOut.indentOut();
+ }
+
+ htmlOut.indentIn();
+ htmlOut.indentIn();
+
+ curLine = "<js fragment=\"" + curHighestFragment + "\"/>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+
+ String jsCode = js[curHighestFragment].substring(range.getStart(),
+ range.getEnd());
+ jsCode = escapeXml(jsCode);
+ if ((jsCode.length() == 0) || (jsCode.compareTo("\n") == 0)) {
+ curLine = "<storyref idref=\"story" + Integer.toString(storyNum) + "\"/>";
+ } else {
+ curLine = "<storyref idref=\"story" + Integer.toString(storyNum) + "\">"
+ + jsCode + "</storyref>";
+ }
+
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+
+ htmlOut.indentOut();
+ htmlOut.indentOut();
+
+ curLine = "</story>";
+ htmlOut.printRaw(curLine);
+ htmlOut.newline();
+ }
+
+ private String escapeXml(String unescaped) {
+ String escaped = unescaped.replaceAll("\\&", "&");
+ escaped = escaped.replaceAll("\\<", "<");
+ escaped = escaped.replaceAll("\\>", ">");
+ escaped = escaped.replaceAll("\\\"", """);
+ // escaped = escaped.replaceAll("\\'", "'");
+ return escaped;
+ }
+}
diff --git a/dev/core/src/com/google/gwt/core/linker/soyc/SoycReportLinker.java b/dev/core/src/com/google/gwt/core/linker/soyc/SoycReportLinker.java
deleted file mode 100644
index 8ab22ab..0000000
--- a/dev/core/src/com/google/gwt/core/linker/soyc/SoycReportLinker.java
+++ /dev/null
@@ -1,827 +0,0 @@
-/*
- * Copyright 2008 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.linker.soyc;
-
-import com.google.gwt.core.ext.LinkerContext;
-import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.linker.AbstractLinker;
-import com.google.gwt.core.ext.linker.ArtifactSet;
-import com.google.gwt.core.ext.linker.CompilationAnalysis;
-import com.google.gwt.core.ext.linker.CompilationResult;
-import com.google.gwt.core.ext.linker.LinkerOrder;
-import com.google.gwt.core.ext.linker.SelectionProperty;
-import com.google.gwt.core.ext.linker.SyntheticArtifact;
-import com.google.gwt.core.ext.linker.CompilationAnalysis.Snippet;
-import com.google.gwt.core.ext.linker.LinkerOrder.Order;
-import com.google.gwt.core.ext.soyc.ClassMember;
-import com.google.gwt.core.ext.soyc.FieldMember;
-import com.google.gwt.core.ext.soyc.FunctionMember;
-import com.google.gwt.core.ext.soyc.Member;
-import com.google.gwt.core.ext.soyc.MethodMember;
-import com.google.gwt.core.ext.soyc.Range;
-import com.google.gwt.core.ext.soyc.Story;
-import com.google.gwt.core.ext.soyc.Story.Origin;
-import com.google.gwt.dev.util.HtmlTextOutput;
-import com.google.gwt.util.tools.Utility;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.zip.GZIPOutputStream;
-
-/**
- * Generates the XML report containing the Story of Your Compile.
- */
-@LinkerOrder(Order.PRE)
-public class SoycReportLinker extends AbstractLinker {
-
- public String escapeXml(String unescaped) {
- String escaped = unescaped.replaceAll("\\&", "&");
- escaped = escaped.replaceAll("\\<", "<");
- escaped = escaped.replaceAll("\\>", ">");
- escaped = escaped.replaceAll("\\\"", """);
- // escaped = escaped.replaceAll("\\'", "'");
- return escaped;
- }
-
- @Override
- public String getDescription() {
- return "Story of your compile report";
- }
-
- @Override
- public ArtifactSet link(TreeLogger logger, LinkerContext context,
- ArtifactSet artifacts) throws UnableToCompleteException {
- SortedSet<CompilationAnalysis> reports = artifacts.find(CompilationAnalysis.class);
-
- // Do nothing if there are no reports to be generated.
- if (reports.isEmpty()) {
- return artifacts;
- }
-
- logger = logger.branch(TreeLogger.DEBUG, "SOYC report linker");
- initialize(logger);
-
- if (reports.isEmpty()) {
- logger.log(TreeLogger.DEBUG, "No SOYC report artifacts");
- return artifacts;
- }
-
- artifacts = new ArtifactSet(artifacts);
- int reportNum = 0;
- SortedMap<CompilationResult, String> partialPathsByResult = new TreeMap<CompilationResult, String>();
-
- // TODO: This goes much faster in parallel, but what's the policy?
- ExecutorService executor = Executors.newSingleThreadExecutor();
- List<Future<SyntheticArtifact>> futures = new ArrayList<Future<SyntheticArtifact>>(
- reports.size());
- for (final CompilationAnalysis report : reports) {
- final TreeLogger loopLogger = logger.branch(TreeLogger.SPAM,
- "Report for " + report.toString());
- final String reportName = "report" + reportNum++ + ".xml.gz";
- partialPathsByResult.put(report.getCompilationResult(), reportName);
- Future<SyntheticArtifact> future = executor.submit(new Callable<SyntheticArtifact>() {
- public SyntheticArtifact call() throws Exception {
- loopLogger.log(TreeLogger.INFO, "Started");
- SyntheticArtifact reportArtifact = emitReport(loopLogger, report,
- reportName, true);
- return reportArtifact;
- }
- });
- futures.add(future);
- }
- executor.shutdown();
-
- for (Future<SyntheticArtifact> future : futures) {
- SyntheticArtifact artifact;
- try {
- artifact = future.get();
- } catch (InterruptedException e) {
- logger.log(TreeLogger.ERROR, "Unable to process report", e);
- throw new UnableToCompleteException();
- } catch (ExecutionException e) {
- logger.log(TreeLogger.ERROR, "Unable to process report", e);
- throw new UnableToCompleteException();
- }
- artifact.setPrivate(true);
- artifacts.add(artifact);
- }
-
- // Emit manifest
- try {
- SyntheticArtifact sa = emitManifest(logger, artifacts,
- partialPathsByResult, false);
- sa.setPrivate(true);
- artifacts.add(sa);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- return artifacts;
- }
-
- private void emitAliases(HtmlTextOutput htmlOut, Set<String> methodAliases) {
- String curLine;
- if (methodAliases.size() > 0) {
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- curLine = "<aliases>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
- }
-
- for (String methodAlias : methodAliases) {
- curLine = "<alias jsName=\"" + methodAlias + "\"/>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- if (methodAliases.size() > 0) {
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</aliases>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentOut();
- htmlOut.indentOut();
- }
- }
-
- private void emitClasses(HtmlTextOutput htmlOut,
- SortedMap<String, Set<ClassMember>> packageToClasses, String packageName) {
- String curLine;
- /**
- * sort the classes alphabetically
- */
- TreeMap<String, ClassMember> sortedClasses = new TreeMap<String, ClassMember>();
- for (ClassMember classMember : packageToClasses.get(packageName)) {
- String className = classMember.getSourceName();
- sortedClasses.put(className, classMember);
- }
-
- for (String className : sortedClasses.keySet()) {
- ClassMember classMember = sortedClasses.get(className);
- curLine = "<class id=\"" + className + "\" ";
- htmlOut.printRaw(curLine);
-
- String jsName = classMember.getJsName();
- String name = className.substring(className.lastIndexOf('.') + 1);
- curLine = "jsName=\"" + jsName + "\" name=\"" + name + "\">";
-
- if (jsName == null) {
- curLine = "name=\"" + name + "\">";
- }
-
- emitOverrides(htmlOut, curLine, classMember);
- emitDependencies(htmlOut, classMember);
- emitMethods(htmlOut, classMember);
- emitFields(htmlOut, classMember);
-
- curLine = "</class>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- }
-
- private void emitDependencies(HtmlTextOutput htmlOut, ClassMember classMember) {
- String curLine;
- Set<Member> dependencies = classMember.getDependencies();
- if (dependencies.size() > 0) {
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- curLine = "<depends>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
- }
- for (Member dependency : dependencies) {
- curLine = "<on idref=\"" + dependency.getSourceName() + "\"/>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- if (dependencies.size() > 0) {
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</depends>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentOut();
- htmlOut.indentOut();
- }
- }
-
- private void emitFields(HtmlTextOutput htmlOut, ClassMember classMember) {
- String curLine;
- Set<FieldMember> fields = classMember.getFields();
- if (fields.size() > 0) {
- htmlOut.indentIn();
- htmlOut.indentIn();
- }
- for (FieldMember field : fields) {
- curLine = "<field id=\"" + field.getSourceName() + "\" jsName=\""
- + field.getJsName() + "\"/>";
- String curJsName = field.getJsName();
- if (curJsName == null) {
- curLine = "<field id=\"" + field.getSourceName() + "\"/>";
- }
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- if (fields.size() > 0) {
- htmlOut.indentOut();
- htmlOut.indentOut();
- }
- }
-
- private void emitFunctions(CompilationAnalysis report, HtmlTextOutput htmlOut) {
- String curLine;
-
- Set<FunctionMember> functions = report.getFunctions();
- for (FunctionMember function : functions) {
- curLine = "<function ";
- htmlOut.printRaw(curLine);
-
- String sourceName = function.getSourceName();
- String jsName = function.getJsName();
- Set<Member> dependencies = function.getDependencies();
- if (dependencies.size() == 0) {
- curLine = "id=\"" + sourceName + "\" jsName=\"" + jsName + "\"/>";
- if (jsName == null) {
- curLine = "id=\"" + sourceName + "\"/>";
- }
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- } else {
- curLine = "id=\"" + sourceName + "\" jsName=\"" + jsName + "\">";
- if (jsName == null) {
- curLine = "id=\"" + sourceName + "\">";
- }
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- curLine = "<depends>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
- }
- for (Member dependency : dependencies) {
- curLine = "<on idref=\"" + dependency.getSourceName() + "\"/>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- if (dependencies.size() > 0) {
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</depends>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</function>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- }
- }
-
- private void emitJs(CompilationAnalysis report, HtmlTextOutput htmlOut,
- Map<Story, Integer> storyIds) {
-
- String curLine;
- int fragment = 0;
- for (String contents : report.getCompilationResult().getJavaScript()) {
- curLine = "<js fragment=\"" + fragment + "\">";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- for (Snippet snippet : report.getSnippets(fragment)) {
- Range range = snippet.getRange();
- Story story = snippet.getStory();
- assert storyIds.containsKey(story);
- int storyId = storyIds.get(story);
-
- String jsCode = contents.substring(range.getStart(), range.getEnd());
- jsCode = escapeXml(jsCode);
- if ((jsCode.length() == 0) || (jsCode.compareTo("\n") == 0)) {
- curLine = "<storyref idref=\"story" + Integer.toString(storyId)
- + "\"/>";
- } else {
- curLine = "<storyref idref=\"story" + Integer.toString(storyId)
- + "\">" + jsCode + "</storyref>";
- }
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
-
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</js>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- fragment++;
- }
- }
-
- private SyntheticArtifact emitManifest(TreeLogger logger,
- ArtifactSet artifacts,
- SortedMap<CompilationResult, String> partialPathsByResult,
- boolean compress) throws UnableToCompleteException, IOException {
-
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- OutputStreamWriter out;
- try {
- out = new OutputStreamWriter(compress ? new GZIPOutputStream(bytes)
- : bytes);
- } catch (IOException e) {
- logger.log(TreeLogger.ERROR, "Unable to set up gzip stream", e);
- throw new UnableToCompleteException();
- }
- PrintWriter pw = new PrintWriter(out);
- HtmlTextOutput htmlOut = new HtmlTextOutput(pw, false);
-
- String curLine = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- curLine = "<soyc-manifest>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- for (Map.Entry<CompilationResult, String> entry : partialPathsByResult.entrySet()) {
- curLine = "<report href=\"" + entry.getValue() + "\">";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- for (Map<SelectionProperty, String> map : entry.getKey().getPropertyMap()) {
-
- if (map.size() > 0) {
- curLine = "<permutation>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- } else {
- curLine = "<permutation/>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- for (Map.Entry<SelectionProperty, String> propertyEntry : map.entrySet()) {
- curLine = "<property name=\"" + propertyEntry.getKey().getName()
- + "\" value=\"" + propertyEntry.getValue() + "\"/>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- if (map.size() > 0) {
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</permutation>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- }
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</report>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
-
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</soyc-manifest>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
-
- pw.close();
- Utility.close(out);
- SyntheticArtifact toReturn = emitBytes(logger, bytes.toByteArray(),
- "manifest.xml");
-
- return toReturn;
- }
-
- private void emitMembers(CompilationAnalysis report, HtmlTextOutput htmlOut) {
-
- String curLine = "<members>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- SortedMap<String, Set<ClassMember>> packageToClasses = new TreeMap<String, Set<ClassMember>>();
-
- emitPackages(report, htmlOut, packageToClasses);
- emitFunctions(report, htmlOut);
-
- htmlOut.indentOut();
- htmlOut.indentOut();
- curLine = "</members>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
-
- private void emitMethodDependencies(HtmlTextOutput htmlOut,
- Set<Member> methodDependencies) {
- String curLine;
- if (methodDependencies.size() > 0) {
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- curLine = "<depends>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- for (Member methodDependency : methodDependencies) {
- curLine = "<on idref=\"" + methodDependency.getSourceName() + "\"/>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
-
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</depends>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentOut();
- htmlOut.indentOut();
- }
- }
-
- private void emitMethodOverrides(HtmlTextOutput htmlOut,
- Set<MethodMember> methodOverrides) {
- String curLine;
- if (methodOverrides.size() > 0) {
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- curLine = "<override>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
- }
- for (MethodMember overrideMethodMember : methodOverrides) {
- curLine = "<of idref=\"" + overrideMethodMember.getSourceName() + "\"/>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- if (methodOverrides.size() > 0) {
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</override>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentOut();
- htmlOut.indentOut();
- }
- }
-
- private void emitMethods(HtmlTextOutput htmlOut, ClassMember classMember) {
- String curLine;
- Set<MethodMember> methods = classMember.getMethods();
- if (methods.size() > 0) {
- htmlOut.indentIn();
- htmlOut.indentIn();
- }
- for (MethodMember method : methods) {
- curLine = "<method ";
- htmlOut.printRaw(curLine);
-
- String jsAtt = " jsName=\"" + method.getJsName() + "\"";
- String curJsName = method.getJsName();
-
- if (curJsName == null) {
- jsAtt = "";
- }
-
- Set<String> methodAliases = method.getJsAliases();
- Set<MethodMember> methodOverrides = method.getOverrides();
- Set<Member> methodDependencies = method.getDependencies();
-
- if ((methodOverrides.size() > 0) || (methodDependencies.size() > 0)
- || (methodAliases.size() > 0)) {
- curLine = "id=\"" + method.getSourceName() + "\"" + jsAtt + ">";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- } else {
- curLine = "id=\"" + method.getSourceName() + "\"" + jsAtt + "/>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
-
- emitAliases(htmlOut, methodAliases);
- emitMethodOverrides(htmlOut, methodOverrides);
- emitMethodDependencies(htmlOut, methodDependencies);
-
- if ((methodOverrides.size() > 0) || (methodDependencies.size() > 0)
- || (methodAliases.size() > 0)) {
- curLine = "</method>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- }
-
- if (methods.size() > 0) {
- htmlOut.indentOut();
- htmlOut.indentOut();
- }
- }
-
- private void emitOverrides(HtmlTextOutput htmlOut, String curLine,
- ClassMember classMember) {
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- Set<ClassMember> overrides = classMember.getOverrides();
- if (overrides.size() > 0) {
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- curLine = "<override>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
- }
- for (ClassMember overrideClassMember : overrides) {
- curLine = "<of idref=\"" + overrideClassMember.getSourceName() + "\"/>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- if (overrides.size() > 0) {
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</override>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentOut();
- htmlOut.indentOut();
- }
- }
-
- private void emitPackages(CompilationAnalysis report, HtmlTextOutput htmlOut,
- SortedMap<String, Set<ClassMember>> packageToClasses) {
-
- String curLine;
- for (ClassMember classMember : report.getClasses()) {
- String packageName = classMember.getPackage();
- if (packageToClasses.containsKey(packageName)) {
- packageToClasses.get(packageName).add(classMember);
- } else {
- Set<ClassMember> insertSet = new HashSet<ClassMember>();
- insertSet.add(classMember);
- packageToClasses.put(packageName, insertSet);
- }
- }
-
- for (String packageName : packageToClasses.keySet()) {
-
- curLine = "<package id=\"" + packageName + "\">";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
-
- if (packageToClasses.get(packageName).size() > 0) {
- htmlOut.indentIn();
- htmlOut.indentIn();
- }
- emitClasses(htmlOut, packageToClasses, packageName);
- if (packageToClasses.get(packageName).size() > 0) {
- htmlOut.indentOut();
- htmlOut.indentOut();
- }
-
- curLine = "</package>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- }
-
- private SyntheticArtifact emitReport(TreeLogger logger,
- CompilationAnalysis report, String partialPath, boolean compress)
- throws UnableToCompleteException, IOException {
-
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- OutputStreamWriter out;
- try {
- out = new OutputStreamWriter(compress ? new GZIPOutputStream(bytes)
- : bytes);
- } catch (IOException e) {
- logger.log(TreeLogger.ERROR, "Unable to set up gzip stream", e);
- throw new UnableToCompleteException();
- }
- PrintWriter pw = new PrintWriter(out);
- HtmlTextOutput htmlOut = new HtmlTextOutput(pw, false);
-
- String curLine = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- curLine = "<soyc>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- Map<Integer, String> splitPointMap = new TreeMap<Integer, String>(
- report.getSplitPointMap());
- if (splitPointMap.size() > 0) {
- curLine = "<splitpoints>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
- for (Integer splitPointCount : splitPointMap.keySet()) {
- curLine = "<splitpoint id=\"" + splitPointCount + "\" location=\""
- + splitPointMap.get(splitPointCount) + "\"/>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- htmlOut.indentOut();
- htmlOut.indentOut();
- curLine = "</splitpoints>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
-
- emitMembers(report, htmlOut);
- Map<Story, Integer> storyIds = emitStories(report, htmlOut);
- emitJs(report, htmlOut, storyIds);
-
- htmlOut.indentOut();
- htmlOut.indentOut();
- curLine = "</soyc>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
-
- pw.close();
- Utility.close(out);
- SyntheticArtifact toReturn = emitBytes(logger, bytes.toByteArray(),
- partialPath);
-
- return toReturn;
- }
-
- private Map<Story, Integer> emitStories(CompilationAnalysis report,
- HtmlTextOutput htmlOut) {
-
- String curLine;
- Map<Story, Integer> storyIds = new HashMap<Story, Integer>();
- Set<Story> stories = report.getStories();
- curLine = "<stories>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
-
- if (stories.size() > 0) {
- htmlOut.indentIn();
- htmlOut.indentIn();
- }
- for (Story story : stories) {
-
- int storyNum = storyIds.size();
- storyIds.put(story, storyNum);
-
- curLine = "<story id=\"story" + Integer.toString(storyNum) + "\"";
- if (story.getLiteralTypeName() != null) {
- curLine = curLine + " literal=\"" + story.getLiteralTypeName() + "\"";
- }
- curLine = curLine + ">";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
-
- Set<Origin> origins = story.getSourceOrigin();
- if (origins.size() > 0) {
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- curLine = "<origins>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- htmlOut.indentIn();
- htmlOut.indentIn();
- }
- for (Origin origin : origins) {
- curLine = "<origin lineNumber=\""
- + Integer.toString(origin.getLineNumber()) + "\" location=\""
- + origin.getLocation() + "\"/>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- if (origins.size() > 0) {
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</origins>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
-
- htmlOut.indentOut();
- htmlOut.indentOut();
- }
-
- Set<Member> correlations = story.getMembers();
- if (correlations.size() > 0) {
- htmlOut.indentIn();
- htmlOut.indentIn();
-
- curLine = "<correlations>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
-
- htmlOut.indentIn();
- htmlOut.indentIn();
- }
- for (Member correlation : correlations) {
- curLine = "<by idref=\"" + correlation.getSourceName() + "\"/>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- if (correlations.size() > 0) {
- htmlOut.indentOut();
- htmlOut.indentOut();
-
- curLine = "</correlations>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
-
- htmlOut.indentOut();
- htmlOut.indentOut();
- }
-
- curLine = "</story>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
- }
- if (stories.size() > 0) {
- htmlOut.indentOut();
- htmlOut.indentOut();
- }
- curLine = "</stories>";
- htmlOut.printRaw(curLine);
- htmlOut.newline();
-
- return storyIds;
- }
-
- private void initialize(TreeLogger logger) throws UnableToCompleteException {
- logger = logger.branch(TreeLogger.SPAM, "Initializing");
- }
-
-}
diff --git a/dev/core/src/com/google/gwt/dev/CompilePerms.java b/dev/core/src/com/google/gwt/dev/CompilePerms.java
index 5efa683..2bfe862 100644
--- a/dev/core/src/com/google/gwt/dev/CompilePerms.java
+++ b/dev/core/src/com/google/gwt/dev/CompilePerms.java
@@ -18,6 +18,7 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.CompileTaskRunner.CompileTask;
+import com.google.gwt.dev.GWTCompiler.GWTCompilerOptionsImpl;
import com.google.gwt.dev.jjs.JavaToJavaScriptCompiler;
import com.google.gwt.dev.jjs.UnifiedAst;
import com.google.gwt.dev.util.FileBackedObject;
@@ -182,7 +183,7 @@
Permutation permutation, UnifiedAst unifiedAst)
throws UnableToCompleteException {
return JavaToJavaScriptCompiler.compilePermutation(logger, unifiedAst,
- permutation.getRebindAnswers());
+ permutation.getRebindAnswers(), permutation.getId());
}
/**
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java b/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
index 050e236..cf8fea0 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
@@ -22,11 +22,12 @@
import com.google.gwt.dev.util.arg.OptionRunAsyncEnabled;
import com.google.gwt.dev.util.arg.OptionScriptStyle;
import com.google.gwt.dev.util.arg.OptionSoycEnabled;
+import com.google.gwt.dev.util.arg.OptionWorkDir;
/**
* Controls options for the {@link JavaToJavaScriptCompiler}.
*/
public interface JJSOptions extends OptionAggressivelyOptimize,
OptionDisableClassMetadata, OptionDraftCompile, OptionEnableAssertions,
- OptionRunAsyncEnabled, OptionScriptStyle, OptionSoycEnabled {
+ OptionRunAsyncEnabled, OptionScriptStyle, OptionSoycEnabled, OptionWorkDir {
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java b/dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java
index 5403614..cb1f9dd 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.dev.jjs;
+import java.io.File;
import java.io.Serializable;
/**
@@ -29,6 +30,7 @@
private JsOutputOption output = JsOutputOption.OBFUSCATED;
private boolean runAsyncEnabled = true;
private boolean soycEnabled = false;
+ private File workDir;
public JJSOptionsImpl() {
}
@@ -45,12 +47,17 @@
setOutput(other.getOutput());
setRunAsyncEnabled(other.isRunAsyncEnabled());
setSoycEnabled(other.isSoycEnabled());
+ setWorkDir(other.getWorkDir());
}
public JsOutputOption getOutput() {
return output;
}
+ public File getWorkDir() {
+ return workDir;
+ }
+
public boolean isAggressivelyOptimize() {
return aggressivelyOptimize;
}
@@ -102,4 +109,8 @@
public void setSoycEnabled(boolean enabled) {
soycEnabled = enabled;
}
+
+ public void setWorkDir(File workDir){
+ this.workDir = workDir;
+ }
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index b5e1739..edadbb8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -20,6 +20,11 @@
import com.google.gwt.core.ext.linker.ArtifactSet;
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;
+import com.google.gwt.core.ext.soyc.StoryRecorder;
+import com.google.gwt.core.ext.soyc.impl.DependencyRecorderImpl;
+import com.google.gwt.core.ext.soyc.impl.SplitPointRecorderImpl;
+import com.google.gwt.core.ext.soyc.impl.StoryRecorderImpl;
import com.google.gwt.dev.PermutationResult;
import com.google.gwt.dev.jdt.RebindPermutationOracle;
import com.google.gwt.dev.jdt.WebModeCompilerFrontEnd;
@@ -94,6 +99,7 @@
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -148,8 +154,8 @@
* {@link OutOfMemoryError} occurs
*/
public static PermutationResult compilePermutation(TreeLogger logger,
- UnifiedAst unifiedAst, Map<String, String> rebindAnswers)
- throws UnableToCompleteException {
+ UnifiedAst unifiedAst, Map<String, String> rebindAnswers,
+ int permutationId) throws UnableToCompleteException {
try {
if (JProgram.isTracingEnabled()) {
System.out.println("------------------------------------------------------------");
@@ -276,11 +282,20 @@
PermutationResult toReturn = new PermutationResultImpl(js, symbolMap);
if (sourceInfoMaps != null) {
- toReturn.getArtifacts().add(
- new StandardCompilationAnalysis(logger, sourceInfoMaps,
- jprogram.getSplitPointMap()));
- }
+ // get method dependencies
+ DependencyRecorderImpl dr = new DependencyRecorderImpl();
+ File depFile = dr.recordDependencies(jprogram, options.getWorkDir(), permutationId, logger);
+
+ StoryRecorder sr = new StoryRecorderImpl();
+ File storyFile = sr.recordStories(jprogram, options.getWorkDir(), permutationId, logger, sourceInfoMaps, js);
+
+ SplitPointRecorder spr = new SplitPointRecorderImpl();
+ File splitPointsFile = spr.recordSplitPoints(jprogram, options.getWorkDir(), permutationId, logger);
+
+ toReturn.getArtifacts().add(
+ new StandardCompilationAnalysis(logger, depFile, storyFile, splitPointsFile));
+ }
return toReturn;
} catch (Throwable e) {
throw logAndTranslateException(logger, e);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java b/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java
index 246a0a2..e9a47f4 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java
@@ -23,6 +23,7 @@
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -32,32 +33,6 @@
public class SourceInfo implements Serializable {
/**
- * Describes how the SourceInfo's node was mutated during the compile cycle.
- */
- public static final class Mutation implements Serializable {
- private final String caller;
- private final String description;
- private final long ts = System.currentTimeMillis();
-
- private Mutation(String description, String caller) {
- this.caller = caller;
- this.description = description;
- }
-
- public String getCaller() {
- return caller;
- }
-
- public String getDescription() {
- return description;
- }
-
- public long getTimestamp() {
- return ts;
- }
- }
-
- /**
* A totally-immutable version of SourceInfo.
*/
protected static class Immutable extends SourceInfo {
@@ -98,13 +73,6 @@
"Unknown source", true);
/**
- * Collecting mutation data is expensive in terms of additional objects and
- * string literals and only of interest to compiler hackers, so we'll just
- * normally have it disabled.
- */
- private static final boolean COLLECT_MUTATIONS = Boolean.getBoolean("gwt.soyc.collectMutations");
-
- /**
* Micro-opt for {@link #makeChild(Class, String)}.
*/
private static final SourceInfo[] EMPTY_SOURCEINFO_ARRAY = new SourceInfo[0];
@@ -117,13 +85,7 @@
/**
* Any Correlation associated with the SourceInfo.
*/
- private final Set<Correlation> allCorrelations;
-
- /**
- * Holds Mutation objects if the compiler is configured to collect mutations.
- */
- private final List<Mutation> mutations = COLLECT_MUTATIONS
- ? new ArrayList<Mutation>() : null;
+ private final List<Correlation> allCorrelations;
/**
* Holds the origin data for the SourceInfo.
@@ -144,41 +106,40 @@
// Be very aggressive in not allocating collections that we don't need.
if (accumulateData) {
- allCorrelations = new HashSet<Correlation>();
+ allCorrelations = new ArrayList<Correlation>();
primaryCorrelations = new EnumMap<Axis, Correlation>(Axis.class);
- // Don't use addCorrelation because of the immutable subclasses
- Correlation originCorrelation = Correlation.by(origin);
- allCorrelations.add(originCorrelation);
- primaryCorrelations.put(Axis.ORIGIN, originCorrelation);
} else {
allCorrelations = null;
primaryCorrelations = null;
}
}
+ private boolean isAlreadyInAllCorrelations(Correlation c) {
+ //make sure this correlations is not yet in the allCorrelations list
+ boolean alreadyThere = false;
+ Iterator<Correlation> it = allCorrelations.iterator();
+ while((alreadyThere == false)&&(it.hasNext())){
+ if (it.next().equals(c)){
+ alreadyThere = true;
+ }
+ }
+ return alreadyThere;
+ }
+
private SourceInfo(SourceInfo parent, String mutation, String caller,
SourceInfo... additionalAncestors) {
assert parent != null;
- assert mutation != null;
assert caller != null;
-
this.accumulateData = parent.accumulateData;
this.origin = parent.origin;
-
if (accumulateData) {
- this.allCorrelations = new HashSet<Correlation>(parent.allCorrelations);
+ this.allCorrelations = new ArrayList<Correlation>(parent.allCorrelations);
this.primaryCorrelations = new EnumMap<Axis, Correlation>(
parent.primaryCorrelations);
} else {
allCorrelations = null;
primaryCorrelations = null;
}
-
- if (COLLECT_MUTATIONS) {
- this.mutations.addAll(parent.mutations);
- this.mutations.add(new Mutation(mutation, caller));
- }
-
merge(additionalAncestors);
}
@@ -189,9 +150,9 @@
if (!accumulateData) {
return;
}
-
- allCorrelations.add(c);
-
+ if (! isAlreadyInAllCorrelations(c)){
+ allCorrelations.add(c);
+ }
if (!primaryCorrelations.containsKey(c.getAxis())) {
primaryCorrelations.put(c.getAxis(), c);
}
@@ -222,21 +183,24 @@
* Returns all Correlations applied to this SourceInfo, its parent, additional
* ancestor SourceInfo, and any supertype SourceInfos.
*/
- public Set<Correlation> getAllCorrelations() {
- return accumulateData ? allCorrelations
- : Collections.<Correlation> emptySet();
+ public List<Correlation> getAllCorrelations() {
+ if (accumulateData){
+ return allCorrelations;
+ }
+ else{
+ return Collections.<Correlation> emptyList();
+ }
}
/**
* Returns all Correlations along a given axis applied to this SourceInfo, its
* parent, additional ancestor SourceInfo, and any supertype SourceInfos.
*/
- public Set<Correlation> getAllCorrelations(Axis axis) {
+ public List<Correlation> getAllCorrelations(Axis axis) {
if (!accumulateData) {
- return Collections.emptySet();
+ return Collections.emptyList();
}
-
- Set<Correlation> toReturn = new HashSet<Correlation>();
+ List<Correlation> toReturn = new ArrayList<Correlation>();
for (Correlation c : getAllCorrelations()) {
if (c.getAxis() == axis) {
toReturn.add(c);
@@ -253,20 +217,6 @@
return getOrigin().getFileName();
}
- /**
- * Returns a summary of the mutations applied to the SourceInfo. It it
- * expensive to collect mutation data, so this method will only return useful
- * values if the <code>gwt.jjs.collectMutations</code> system property is
- * defined.
- */
- public List<Mutation> getMutations() {
- if (COLLECT_MUTATIONS) {
- return mutations;
- } else {
- return Collections.emptyList();
- }
- }
-
public SourceOrigin getOrigin() {
return origin;
}
@@ -338,7 +288,11 @@
continue;
}
- allCorrelations.addAll(info.getAllCorrelations());
+ for (Correlation c : info.getAllCorrelations()){
+ if (! isAlreadyInAllCorrelations(c)){
+ allCorrelations.add(c);
+ }
+ }
if (primaryCorrelations.size() < Axis.values().length) {
EnumMap<Axis, Correlation> copy = new EnumMap<Axis, Correlation>(
@@ -346,10 +300,6 @@
copy.keySet().removeAll(primaryCorrelations.keySet());
primaryCorrelations.putAll(copy);
}
-
- if (COLLECT_MUTATIONS) {
- mutations.addAll(0, info.getMutations());
- }
}
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
index f2868c3..eb09959 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
@@ -68,6 +68,18 @@
* execution at a specified location.
*/
public class ControlFlowAnalyzer {
+ /**
+ * A callback for recording control-flow dependencies as they are discovered.
+ * See {@link ControlFlowAnalyzer#setDependencyRecorder(DependencyRecorder)}.
+ */
+ public interface DependencyRecorder {
+
+ /**
+ * Used to record the dependencies of a specific method
+ */
+ void methodIsLiveBecause(JMethod liveMethod,
+ ArrayList<JMethod> dependencyChain);
+ }
/**
* Marks as "referenced" any types, methods, and fields that are reachable.
@@ -77,6 +89,8 @@
* TODO(later): make RescueVisitor use less stack?
*/
private class RescueVisitor extends JVisitor {
+ private ArrayList<JMethod> curMethodStack = new ArrayList<JMethod>();
+
@Override
public boolean visit(JArrayType type, Context ctx) {
assert (referencedTypes.contains(type));
@@ -477,9 +491,14 @@
if (!liveFieldsAndMethods.contains(method)) {
liveFieldsAndMethods.add(method);
methodsLiveExceptForInstantiability.remove(method);
-
+ if (dependencyRecorder != null) {
+ curMethodStack.add(method);
+ dependencyRecorder.methodIsLiveBecause(method, curMethodStack);
+ }
accept(method);
-
+ if (dependencyRecorder != null) {
+ curMethodStack.remove(curMethodStack.size() - 1);
+ }
if (method.isNative()) {
/*
* SPECIAL: returning from this method passes a value from
@@ -487,9 +506,7 @@
*/
maybeRescueJavaScriptObjectPassingIntoJava(method.getType());
}
-
rescueOverridingMethods(method);
-
return true;
}
}
@@ -638,6 +655,8 @@
}
}
+ private DependencyRecorder dependencyRecorder;
+
private Set<JField> fieldsWritten = new HashSet<JField>();
private Set<JReferenceType> instantiatedTypes = new HashSet<JReferenceType>();
private Set<JNode> liveFieldsAndMethods = new HashSet<JNode>();
@@ -714,6 +733,18 @@
}
/**
+ * Specify the {@link DependencyRecorder} to be used for future traversals.
+ * Specifying <code>null</code> means to stop recording dependencies.
+ */
+ public void setDependencyRecorder(DependencyRecorder dr) {
+ if (dependencyRecorder != null && dr != null) {
+ throw new IllegalArgumentException(
+ "Attempting to set multiple dependency recorders");
+ }
+ this.dependencyRecorder = dr;
+ }
+
+ /**
* Traverse all code executed by <code>expr</code>.
*/
public void traverseFrom(JExpression expr) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index 079e17f..b9c5310 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -163,7 +163,6 @@
String mangleName = mangleName(x);
if (x.isStatic()) {
JsName jsName = topScope.declareName(mangleName, name);
- x.getSourceInfo().addCorrelation(Correlation.by(jsName));
names.put(x, jsName);
recordSymbol(x, jsName);
} else {
@@ -177,7 +176,6 @@
} else {
jsName = peek().declareName(mangleName, name);
}
- x.getSourceInfo().addCorrelation(Correlation.by(jsName));
names.put(x, jsName);
recordSymbol(x, jsName);
}
@@ -245,7 +243,6 @@
// My seed function name
JsName jsName = topScope.declareName(getNameString(x), x.getShortName());
- x.getSourceInfo().addCorrelation(Correlation.by(jsName));
names.put(x, jsName);
recordSymbol(x, jsName);
@@ -331,7 +328,6 @@
jsFunction = new JsFunction(sourceInfo, topScope, globalName, true);
}
methodBodyMap.put(x.getBody(), jsFunction);
- jsFunction.getSourceInfo().addCorrelation(Correlation.by(jsFunction));
jsFunction.getSourceInfo().addCorrelation(Correlation.by(globalName));
push(jsFunction.getScope());
return true;
@@ -1399,7 +1395,6 @@
gwtOnLoadName.setObfuscatable(false);
JsFunction gwtOnLoad = new JsFunction(sourceInfo, topScope,
gwtOnLoadName, true);
- sourceInfo.addCorrelation(Correlation.by(gwtOnLoad));
globalStmts.add(gwtOnLoad.makeStmt());
JsBlock body = new JsBlock(sourceInfo);
gwtOnLoad.setBody(body);
@@ -1461,7 +1456,6 @@
GenerateJavaScriptAST.class, "Null function");
JsFunction nullFunc = new JsFunction(sourceInfo, topScope,
nullMethodName, true);
- sourceInfo.addCorrelation(Correlation.by(nullFunc));
nullFunc.setBody(new JsBlock(sourceInfo));
globalStatements.add(nullFunc.makeStmt());
}
@@ -1478,7 +1472,6 @@
JsFunction seedFunc = new JsFunction(sourceInfo, topScope,
seedFuncName, true);
seedFuncName.setStaticRef(seedFunc);
- sourceInfo.addCorrelation(Correlation.by(seedFunc));
JsBlock body = new JsBlock(sourceInfo);
seedFunc.setBody(body);
JsExprStmt seedFuncStmt = seedFunc.makeStmt();
diff --git a/tools/soyc-vis/src/com/google/gwt/soyc/CodeCollection.java b/tools/soyc-vis/src/com/google/gwt/soyc/CodeCollection.java
index 655b516..27ae797 100644
--- a/tools/soyc-vis/src/com/google/gwt/soyc/CodeCollection.java
+++ b/tools/soyc-vis/src/com/google/gwt/soyc/CodeCollection.java
@@ -19,41 +19,40 @@
import java.util.TreeSet;
public class CodeCollection {
-
+
public String codeType = "";
public TreeSet<String> classes = new TreeSet<String>();
public TreeSet<String> stories = new TreeSet<String>();
public float cumPartialSize = 0f;
public int cumSize = 0;
-
-
- public CodeCollection(String type){
+
+ public CodeCollection(String type) {
codeType = type;
}
-
- public int getCumSize(){
+
+ public int getCumSize() {
cumSize = 0;
- for (String className : classes){
- if (! GlobalInformation.classToSize.containsKey(className)){
- System.err.println("*** NO SIZE FOUND FOR CLASS " + className + " *****");
- }
- else{
+ for (String className : classes) {
+ if (!GlobalInformation.classToSize.containsKey(className)) {
+ System.err.println("*** NO SIZE FOUND FOR CLASS " + className
+ + " *****");
+ } else {
cumSize += GlobalInformation.classToSize.get(className);
}
}
return cumSize;
- }
-
- public float getCumPartialSize(){
+ }
+
+ public float getCumPartialSize() {
cumPartialSize = 0f;
- for (String className : classes){
- if (!GlobalInformation.classToPartialSize.containsKey(className)){
- System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className + " *****");
- }
- else{
+ for (String className : classes) {
+ if (!GlobalInformation.classToPartialSize.containsKey(className)) {
+ System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className
+ + " *****");
+ } else {
cumPartialSize += GlobalInformation.classToPartialSize.get(className);
}
}
return cumPartialSize;
- }
+ }
}
diff --git a/tools/soyc-vis/src/com/google/gwt/soyc/GlobalInformation.java b/tools/soyc-vis/src/com/google/gwt/soyc/GlobalInformation.java
index bdba9be..bc2c418 100644
--- a/tools/soyc-vis/src/com/google/gwt/soyc/GlobalInformation.java
+++ b/tools/soyc-vis/src/com/google/gwt/soyc/GlobalInformation.java
@@ -14,7 +14,6 @@
* the License.
*/
-
package com.google.gwt.soyc;
import java.util.HashMap;
@@ -23,25 +22,25 @@
import java.util.TreeSet;
public class GlobalInformation {
-
+
public static Boolean displayDependencies = false;
-
+ public static Boolean displaySplitPoints = false;
+
public static int allOtherFragmentsPartialSize = 0;
public static HashMap<String, String> classToPackage = new HashMap<String, String>();
public static HashMap<String, Float> classToPartialSize = new HashMap<String, Float>();
public static HashMap<String, Integer> classToSize = new HashMap<String, Integer>();
- //TODO(kprobst): not currently used, but will be for dependencies
public static HashMap<String, HashSet<String>> classToWhatItDependsOn = new HashMap<String, HashSet<String>>();
public static float cumPartialSizeFromPackages = 0f;
- public static int cumSizeAllCode = 0;
+ public static int cumSizeAllCode = 0;
public static int cumSizeFromPackages = 0;
public static int cumSizeInitialFragment = 0;
- public static HashMap<Integer, Float> fragmentToPartialSize = new HashMap<Integer, Float>(); //collect only size for exclusive fragments
+ // collect only size for exclusive fragments
+ public static HashMap<Integer, Float> fragmentToPartialSize = new HashMap<Integer, Float>();
public static HashMap<Integer, HashSet<String>> fragmentToStories = new HashMap<Integer, HashSet<String>>();
public static TreeMap<String, LiteralsCollection> nameToLitColl = new TreeMap<String, LiteralsCollection>();
public static HashMap<String, CodeCollection> nameToCodeColl = new HashMap<String, CodeCollection>();
-
public static int nonAttributedBytes = 0;
public static HashSet<String> nonAttributedStories = new HashSet<String>();
public static int numBytesDoubleCounted = 0;
@@ -53,19 +52,19 @@
public static HashMap<Integer, String> splitPointToLocation = new HashMap<Integer, String>();
public static HashMap<String, HashSet<String>> storiesToCorrClasses = new HashMap<String, HashSet<String>>();
public static HashMap<String, HashSet<String>> storiesToCorrClassesAndMethods = new HashMap<String, HashSet<String>>();
-
+
public static HashMap<String, String> storiesToLitType = new HashMap<String, String>();
-
- public static void computePackageSizes(){
+
+ public static void computePackageSizes() {
cumSizeFromPackages = 0;
packageToSize.clear();
- for (String packageName : packageToClasses.keySet()){
+ for (String packageName : packageToClasses.keySet()) {
packageToSize.put(packageName, 0);
- for (String className : packageToClasses.get(packageName)){
- if (! classToSize.containsKey(className)){
- System.err.println("*** NO SIZE FOUND FOR CLASS " + className + " *****");
- }
- else{
+ for (String className : packageToClasses.get(packageName)) {
+ if (!classToSize.containsKey(className)) {
+ System.err.println("*** NO SIZE FOUND FOR CLASS " + className
+ + " *****");
+ } else {
int curSize = classToSize.get(className);
cumSizeFromPackages += curSize;
int newSize = curSize + packageToSize.get(packageName);
@@ -74,16 +73,17 @@
}
}
}
- public static void computePartialPackageSizes(){
+
+ public static void computePartialPackageSizes() {
cumPartialSizeFromPackages = 0;
packageToPartialSize.clear();
- for (String packageName : packageToClasses.keySet()){
+ for (String packageName : packageToClasses.keySet()) {
packageToPartialSize.put(packageName, 0f);
- for (String className : packageToClasses.get(packageName)){
- if (! classToPartialSize.containsKey(className)){
- System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className + " *****");
- }
- else{
+ for (String className : packageToClasses.get(packageName)) {
+ if (!classToPartialSize.containsKey(className)) {
+ System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className
+ + " *****");
+ } else {
float curSize = classToPartialSize.get(className);
cumPartialSizeFromPackages += curSize;
float newSize = curSize + packageToPartialSize.get(packageName);
diff --git a/tools/soyc-vis/src/com/google/gwt/soyc/MakeTopLevelHtmlForPerm.java b/tools/soyc-vis/src/com/google/gwt/soyc/MakeTopLevelHtmlForPerm.java
index 7712e0b..8a3669f 100644
--- a/tools/soyc-vis/src/com/google/gwt/soyc/MakeTopLevelHtmlForPerm.java
+++ b/tools/soyc-vis/src/com/google/gwt/soyc/MakeTopLevelHtmlForPerm.java
@@ -26,7 +26,6 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
@@ -35,23 +34,24 @@
import java.util.jar.JarInputStream;
public class MakeTopLevelHtmlForPerm {
-
- private static void makePackageHtml(String outFileName) throws IOException{
-
-
- TreeMap<Float, String> sortedPackages = new TreeMap<Float, String>(Collections.reverseOrder());
+
+ private static void makePackageHtml(String outFileName) throws IOException {
+
+ TreeMap<Float, String> sortedPackages = new TreeMap<Float, String>(
+ Collections.reverseOrder());
float maxSize = 0f;
float sumSize = 0f;
- for (String packageName : GlobalInformation.packageToPartialSize.keySet()){
- sortedPackages.put(GlobalInformation.packageToPartialSize.get(packageName), packageName);
+ for (String packageName : GlobalInformation.packageToPartialSize.keySet()) {
+ sortedPackages.put(
+ GlobalInformation.packageToPartialSize.get(packageName), packageName);
sumSize += GlobalInformation.packageToPartialSize.get(packageName);
- if (GlobalInformation.packageToPartialSize.get(packageName) > maxSize){
+ if (GlobalInformation.packageToPartialSize.get(packageName) > maxSize) {
maxSize = GlobalInformation.packageToPartialSize.get(packageName);
}
}
-
+
final PrintWriter outFile = new PrintWriter(outFileName);
-
+
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
@@ -63,20 +63,21 @@
outFile.println("<body>");
int yOffset = 0;
- for (Float size : sortedPackages.keySet()){
-
+ for (Float size : sortedPackages.keySet()) {
+
String packageName = sortedPackages.get(size);
String drillDownFileName = packageName + "Classes.html";
-
+
float ratio = (size / maxSize) * 79;
-
- if (ratio < 3){
+
+ if (ratio < 3) {
ratio = 3;
}
float perc = (size / sumSize) * 100;
-
- outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 110px;\">");
+
+ outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: "
+ + yOffset + "px; left: 110px;\">");
outFile.println("<div id=\"lb\">");
outFile.println("<div id=\"rb\">");
outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -86,66 +87,64 @@
outFile.println("</div></div></div></div>");
outFile.println("</div></div></div></div>");
outFile.println("</div>");
-
- int yOffsetText = yOffset+8;
- outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
- outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:70px;\">%.1f", perc);
+
+ int yOffsetText = yOffset + 8;
+ outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:5px;\">%.1f</div>\n", size);
+ outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:70px;\">%.1f", perc);
outFile.println("%</div>\n");
- outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:110px;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">"+packageName+"</a></div>");
-
+ outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:110px;\"><a href=\"" + drillDownFileName
+ + "\" target=\"_top\">" + packageName + "</a></div>");
+
yOffset = yOffset + 25;
}
outFile.println("</body>");
outFile.println("</html>");
outFile.close();
-
+
}
-
- private static void makeFragmentsHtml(String outFileName) throws IOException{
-
- // TreeMap<Float, Integer> sortedFragments = new TreeMap<Float, Integer>(Collections.reverseOrder());
- TreeMap<Float, String> sortedSplitPoints = new TreeMap<Float, String>(Collections.reverseOrder());
+
+ private static void makeFragmentsHtml(String outFileName) throws IOException {
+
+ // TreeMap<Float, Integer> sortedFragments = new TreeMap<Float,
+ // Integer>(Collections.reverseOrder());
+ TreeMap<Float, String> sortedSplitPoints = new TreeMap<Float, String>(
+ Collections.reverseOrder());
float maxSize = 0f;
float sumSize = 0f;
-
+
// initial fragment
float initialSize = GlobalInformation.fragmentToPartialSize.get(0);
sumSize += initialSize;
maxSize = initialSize;
sortedSplitPoints.put(initialSize, "initialDownload");
-
+
// all fragments that are not in the initial load order
float allOtherFragmentsSize = GlobalInformation.allOtherFragmentsPartialSize;
sumSize += allOtherFragmentsSize;
- if (allOtherFragmentsSize > maxSize){
+ if (allOtherFragmentsSize > maxSize) {
maxSize = allOtherFragmentsSize;
}
sortedSplitPoints.put(allOtherFragmentsSize, "allOtherFragments");
-
+
// all exclusive fragments
System.out.println("");
- for (Integer splitPointId : GlobalInformation.splitPointToLocation.keySet()){
+ for (Integer splitPointId : GlobalInformation.splitPointToLocation.keySet()) {
System.out.println("splitPointId is: " + splitPointId);
Float sizeOfCurExclusiveFrag = GlobalInformation.fragmentToPartialSize.get(splitPointId);
- sortedSplitPoints.put(sizeOfCurExclusiveFrag, GlobalInformation.splitPointToLocation.get(splitPointId));
+ sortedSplitPoints.put(sizeOfCurExclusiveFrag,
+ GlobalInformation.splitPointToLocation.get(splitPointId));
sumSize += sizeOfCurExclusiveFrag;
- if (sizeOfCurExclusiveFrag > maxSize){
+ if (sizeOfCurExclusiveFrag > maxSize) {
maxSize = sizeOfCurExclusiveFrag;
}
}
-
-
-/* for (Integer fragmentName : GlobalInformation.fragmentToPartialSize.keySet()){
- sortedFragments.put(GlobalInformation.fragmentToPartialSize.get(fragmentName), fragmentName);
- sumSize += GlobalInformation.fragmentToPartialSize.get(fragmentName);
- if (GlobalInformation.fragmentToPartialSize.get(fragmentName) > maxSize){
- maxSize = GlobalInformation.fragmentToPartialSize.get(fragmentName);
- }
- }*/
-
+
final PrintWriter outFile = new PrintWriter(outFileName);
-
+
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
@@ -156,23 +155,18 @@
outFile.println("<body>");
int yOffset = 0;
- //for (Float size : sortedFragments.keySet()){
- for (Float size : sortedSplitPoints.keySet()){
-
- // Integer fragmentName = sortedFragments.get(size);
+ for (Float size : sortedSplitPoints.keySet()) {
String splitPointName = sortedSplitPoints.get(size);
- // String drillDownFileName = "fragment" + Integer.toString(fragmentName) + "Classes.html";
String drillDownFileName = "splitPoint" + splitPointName + "Classes.html";
-
+
float ratio = (size / maxSize) * 79;
-
- if (ratio < 3){
+ if (ratio < 3) {
ratio = 3;
}
-
float perc = (size / sumSize) * 100;
-
- outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 110px;\">");
+
+ outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: "
+ + yOffset + "px; left: 110px;\">");
outFile.println("<div id=\"lb\">");
outFile.println("<div id=\"rb\">");
outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -182,45 +176,50 @@
outFile.println("</div></div></div></div>");
outFile.println("</div></div></div></div>");
outFile.println("</div>");
-
- int yOffsetText = yOffset+8;
- outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
- outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:80px;\">%.1f", perc);
+
+ int yOffsetText = yOffset + 8;
+ outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:5px;\">%.1f</div>\n", size);
+ outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:80px;\">%.1f", perc);
outFile.println("%</div>\n");
- // outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:120px;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">fragment"+ Integer.toString(fragmentName) +"</a></div>");
- outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:120px;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">"+ splitPointName +"</a></div>");
-
+ outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:120px;\"><a href=\"" + drillDownFileName
+ + "\" target=\"_top\">" + splitPointName + "</a></div>");
+
yOffset = yOffset + 25;
}
outFile.println("</body>");
outFile.println("</html>");
outFile.close();
-
+
}
- private static void makeCodeTypeHtml(String outFileName, HashMap<String, CodeCollection> nameToCodeColl) throws IOException{
-
-
+ private static void makeCodeTypeHtml(String outFileName,
+ HashMap<String, CodeCollection> nameToCodeColl) throws IOException {
+
float maxSize = 0f;
float sumSize = 0f;
- TreeMap<Float, String> sortedCodeTypes = new TreeMap<Float, String>(Collections.reverseOrder());
-
- //TODO(kprobst): turn this into a multimap? com.google.common.collect.TreeMultimap
- for (String codeType : nameToCodeColl.keySet()){
+ TreeMap<Float, String> sortedCodeTypes = new TreeMap<Float, String>(
+ Collections.reverseOrder());
+
+ // TODO(kprobst): turn this into a multimap?
+ // com.google.common.collect.TreeMultimap
+ for (String codeType : nameToCodeColl.keySet()) {
float curSize = nameToCodeColl.get(codeType).getCumPartialSize();
sumSize += curSize;
-
- if (curSize != 0f){
+
+ if (curSize != 0f) {
sortedCodeTypes.put(curSize, codeType);
- if (curSize > maxSize){
+ if (curSize > maxSize) {
maxSize = curSize;
}
}
}
-
+
final PrintWriter outFile = new PrintWriter(outFileName);
-
+
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
@@ -231,19 +230,20 @@
outFile.println("<body>");
int yOffset = 0;
- for (Float size : sortedCodeTypes.keySet()){
-
+ for (Float size : sortedCodeTypes.keySet()) {
+
String codeType = sortedCodeTypes.get(size);
String drillDownFileName = codeType + "Classes.html";
-
- float ratio = (size / maxSize) * 79;
+
+ float ratio = (size / maxSize) * 79;
float perc = (size / sumSize) * 100;
-
- if (ratio < 3){
+
+ if (ratio < 3) {
ratio = 3;
}
- outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 110px;\">");
+ outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: "
+ + yOffset + "px; left: 110px;\">");
outFile.println("<div id=\"lb\">");
outFile.println("<div id=\"rb\">");
outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -253,46 +253,49 @@
outFile.println("</div></div></div></div>");
outFile.println("</div></div></div></div>");
outFile.println("</div>");
-
- int yOffsetText = yOffset+8;
- outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
- outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:70px;\">%.1f", perc);
+
+ int yOffsetText = yOffset + 8;
+ outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:5px;\">%.1f</div>\n", size);
+ outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:70px;\">%.1f", perc);
outFile.println("%</div>\n");
- outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:110px;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">"+codeType+"</a></div>");
-
+ outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:110px;\"><a href=\"" + drillDownFileName
+ + "\" target=\"_top\">" + codeType + "</a></div>");
+
yOffset = yOffset + 25;
}
outFile.println("</body>");
outFile.println("</html>");
outFile.close();
-
-
+
}
-
- private static void makeLiteralsHtml(String outFileName, TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
-
+
+ private static void makeLiteralsHtml(String outFileName,
+ TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
float maxSize = 0f;
float sumSize = 0f;
- TreeMap<Float, String> sortedLitTypes = new TreeMap<Float, String>(Collections.reverseOrder());
-
- for (String literal : nameToLitColl.keySet()){
+ TreeMap<Float, String> sortedLitTypes = new TreeMap<Float, String>(
+ Collections.reverseOrder());
+
+ for (String literal : nameToLitColl.keySet()) {
float curSize = nameToLitColl.get(literal).cumSize;
sumSize += curSize;
-
- if (curSize != 0f){
+
+ if (curSize != 0f) {
sortedLitTypes.put(curSize, literal);
-
- if (curSize > maxSize){
+
+ if (curSize > maxSize) {
maxSize = curSize;
}
}
}
-
final PrintWriter outFile = new PrintWriter(outFileName);
-
+
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
@@ -303,19 +306,20 @@
outFile.println("<body>");
int yOffset = 0;
- for (Float size : sortedLitTypes.keySet()){
-
+ for (Float size : sortedLitTypes.keySet()) {
+
String literal = sortedLitTypes.get(size);
String drillDownFileName = literal + "Lits.html";
-
- float ratio = (size / maxSize) * 79;
+
+ float ratio = (size / maxSize) * 79;
float perc = (size / sumSize) * 100;
-
- if (ratio < 3){
+
+ if (ratio < 3) {
ratio = 3;
}
-
- outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 110px;\">");
+
+ outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: "
+ + yOffset + "px; left: 110px;\">");
outFile.println("<div id=\"lb\">");
outFile.println("<div id=\"rb\">");
outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -325,26 +329,31 @@
outFile.println("</div></div></div></div>");
outFile.println("</div></div></div></div>");
outFile.println("</div>");
-
- int yOffsetText = yOffset+8;
- outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
- outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:70px;\">%.1f", perc);
+
+ int yOffsetText = yOffset + 8;
+ outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:5px;\">%.1f</div>\n", size);
+ outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:70px;\">%.1f", perc);
outFile.println("%</div>\n");
- outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:110px;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">"+literal+"</a></div>");
-
+ outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:110px;\"><a href=\"" + drillDownFileName
+ + "\" target=\"_top\">" + literal + "</a></div>");
+
yOffset = yOffset + 25;
}
outFile.println("</body>");
outFile.println("</html>");
outFile.close();
-
+
}
-
- private static void makeStringLiteralsHtml(String outFileName, TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
+
+ private static void makeStringLiteralsHtml(String outFileName,
+ TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
final PrintWriter outFile = new PrintWriter(outFileName);
-
+
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
@@ -353,42 +362,42 @@
outFile.println("<link rel=\"stylesheet\" href=\"roundedCorners.css\" media=\"screen\">");
outFile.println("</head>");
outFile.println("<body>");
-
-
- if (nameToLitColl.get("string").stringTypeToSize.size() > 0){
-
+
+ if (nameToLitColl.get("string").stringTypeToSize.size() > 0) {
+
float maxSize = 0f;
float sumSize = 0f;
- TreeMap<Float, String> sortedStLitTypes = new TreeMap<Float, String>(Collections.reverseOrder());
-
- for (String stringLiteral : nameToLitColl.get("string").stringTypeToSize.keySet()){
+ TreeMap<Float, String> sortedStLitTypes = new TreeMap<Float, String>(
+ Collections.reverseOrder());
+
+ for (String stringLiteral : nameToLitColl.get("string").stringTypeToSize.keySet()) {
float curSize = nameToLitColl.get("string").stringTypeToSize.get(stringLiteral);
sumSize += curSize;
-
- if (curSize != 0f){
+
+ if (curSize != 0f) {
sortedStLitTypes.put(curSize, stringLiteral);
-
- if (curSize > maxSize){
+
+ if (curSize > maxSize) {
maxSize = curSize;
}
}
}
-
int yOffset = 0;
- for (Float size : sortedStLitTypes.keySet()){
-
+ for (Float size : sortedStLitTypes.keySet()) {
+
String stringLiteral = sortedStLitTypes.get(size);
String drillDownFileName = stringLiteral + "Strings.html";
-
+
float ratio = (size / maxSize) * 79;
float perc = (size / sumSize) * 100;
-
- if (ratio < 3){
+
+ if (ratio < 3) {
ratio = 3;
}
-
- outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 110px;\">");
+
+ outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: "
+ + yOffset + "px; left: 110px;\">");
outFile.println("<div id=\"lb\">");
outFile.println("<div id=\"rb\">");
outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -398,82 +407,92 @@
outFile.println("</div></div></div></div>");
outFile.println("</div></div></div></div>");
outFile.println("</div>");
-
- int yOffsetText = yOffset+8;
- outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
- outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:70px;\">%.1f", perc);
+
+ int yOffsetText = yOffset + 8;
+ outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:5px;\">%.1f</div>\n", size);
+ outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:70px;\">%.1f", perc);
outFile.println("%</div>\n");
- outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:110px;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">"+stringLiteral+"</a></div>");
-
+ outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:110px;\"><a href=\"" + drillDownFileName
+ + "\" target=\"_top\">" + stringLiteral + "</a></div>");
+
yOffset = yOffset + 25;
-
+
}
-
+
}
-
- else{
+
+ else {
outFile.println("No string literals found for this application.");
-
+
}
outFile.println("</body>");
outFile.println("</html>");
outFile.close();
}
-
- public static void copyFileOrDirectoryFromJar(String jarFileName, String inputFileName, File dstPath, boolean isDirectory) throws IOException{
+ public static void copyFileOrDirectoryFromJar(String jarFileName,
+ String inputFileName, File dstPath, boolean isDirectory)
+ throws IOException {
JarFile jarFile = new JarFile(jarFileName);
- if (isDirectory){
+ if (isDirectory) {
dstPath.mkdir();
-
- JarInputStream jarFileIS = new JarInputStream(new FileInputStream(jarFileName));
+
+ JarInputStream jarFileIS = new JarInputStream(new FileInputStream(
+ jarFileName));
JarEntry jarEntry = jarFileIS.getNextJarEntry();
- while(jarEntry != null){
- if (! inputFileName.endsWith("/")){
+ while (jarEntry != null) {
+ if (!inputFileName.endsWith("/")) {
inputFileName += "/";
}
- if ((jarEntry.getName().compareTo(inputFileName) != 0)&&(jarEntry.getName().startsWith(inputFileName))){
- File newDstPath = new File(jarEntry.getName());
- copyFileOrDirectoryFromJar(jarFileName, jarEntry.getName(), newDstPath, false);
- }
+ if ((jarEntry.getName().compareTo(inputFileName) != 0)
+ && (jarEntry.getName().startsWith(inputFileName))) {
+ File newDstPath = new File(jarEntry.getName());
+ copyFileOrDirectoryFromJar(jarFileName, jarEntry.getName(),
+ newDstPath, false);
+ }
jarEntry = jarFileIS.getNextJarEntry();
}
jarFileIS.close();
}
- else{
+ else {
InputStream in = jarFile.getInputStream(jarFile.getEntry(inputFileName));
- OutputStream out = new FileOutputStream(dstPath);
-
+ OutputStream out = new FileOutputStream(dstPath);
+
int c;
- while ((c = in.read()) != -1){
- out.write(c);
+ while ((c = in.read()) != -1) {
+ out.write(c);
}
in.close();
out.close();
jarFile.close();
}
}
-
- public static void copyFileOrDirectory(File srcPath, File dstPath, String classPath, String inputFileName, boolean isDirectory) throws IOException{
- if (srcPath.isDirectory()){
- if (!dstPath.exists()){
+
+ public static void copyFileOrDirectory(File srcPath, File dstPath,
+ String classPath, String inputFileName, boolean isDirectory)
+ throws IOException {
+ if (srcPath.isDirectory()) {
+ if (!dstPath.exists()) {
dstPath.mkdir();
- }
- String files[] = srcPath.list();
- for(int i = 0; i < files.length; i++){
- copyFileOrDirectory(new File(srcPath, files[i]), new File(dstPath, files[i]), classPath, inputFileName, isDirectory);
}
- }
- else{
- if(!srcPath.exists()){
- copyFileOrDirectoryFromJar(classPath, inputFileName, dstPath, isDirectory);
- }
- else{
+ String files[] = srcPath.list();
+ for (int i = 0; i < files.length; i++) {
+ copyFileOrDirectory(new File(srcPath, files[i]), new File(dstPath,
+ files[i]), classPath, inputFileName, isDirectory);
+ }
+ } else {
+ if (!srcPath.exists()) {
+ copyFileOrDirectoryFromJar(classPath, inputFileName, dstPath,
+ isDirectory);
+ } else {
InputStream in = new FileInputStream(srcPath);
- OutputStream out = new FileOutputStream(dstPath);
+ OutputStream out = new FileOutputStream(dstPath);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
@@ -482,8 +501,8 @@
}
in.close();
out.close();
- }
- }
+ }
+ }
}
public static String escapeXml(String unescaped) {
@@ -495,77 +514,76 @@
return escaped;
}
- public static void makeCodeTypeClassesHtmls(HashMap<String, CodeCollection> nameToCodeColl) throws IOException{
-
- for (String codeType : nameToCodeColl.keySet()){
-
- //construct file name
+ public static void makeCodeTypeClassesHtmls(
+ HashMap<String, CodeCollection> nameToCodeColl) throws IOException {
+
+ for (String codeType : nameToCodeColl.keySet()) {
+
+ // construct file name
String outFileName = codeType + "Classes.html";
-
-
+
float maxSize = 0f;
- TreeMap<Float, String> sortedClasses = new TreeMap<Float, String>(Collections.reverseOrder());
- for (String className : nameToCodeColl.get(codeType).classes){
- if (GlobalInformation.classToPartialSize.containsKey(className)){
-
+ TreeMap<Float, String> sortedClasses = new TreeMap<Float, String>(
+ Collections.reverseOrder());
+ for (String className : nameToCodeColl.get(codeType).classes) {
+ if (GlobalInformation.classToPartialSize.containsKey(className)) {
+
float curSize = 0f;
- if (! GlobalInformation.classToPartialSize.containsKey(className)){
- System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className + " *****");
- }
- else{
+ if (!GlobalInformation.classToPartialSize.containsKey(className)) {
+ System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS "
+ + className + " *****");
+ } else {
curSize = GlobalInformation.classToPartialSize.get(className);
}
-
- if (curSize != 0f){
+
+ if (curSize != 0f) {
sortedClasses.put(curSize, className);
- if (curSize > maxSize){
+ if (curSize > maxSize) {
maxSize = curSize;
}
}
}
}
-
+
final PrintWriter outFile = new PrintWriter(outFileName);
-
+
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
outFile.println("<head>");
-
+
outFile.println("<style type=\"text/css\">");
outFile.println("body {background-color: #728FCE}");
outFile.println("h2 {background-color: transparent}");
outFile.println("p {background-color: fuchsia}");
outFile.println("</style>");
-
+
outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
outFile.println("<link rel=\"stylesheet\" href=\"classLevel.css\" media=\"screen\">");
outFile.println("<title>Classes of type \"" + codeType + "\"</title>");
outFile.println("</head>");
outFile.println("<body>");
-
-
-
+
outFile.println("<center>");
outFile.println("<h2>Classes of type \"" + codeType + "\"</h2>");
outFile.println("</center>");
outFile.println("<hr>");
-
+
outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 90px; left:70px; position:absolute; background-color:white\"");
-
-
+
int yOffset = 0;
- for (Float size : sortedClasses.keySet()){
-
+ for (Float size : sortedClasses.keySet()) {
+
String className = sortedClasses.get(size);
-
+
float ratio = (size / maxSize) * 85;
-
- if (ratio < 3){
+
+ if (ratio < 3) {
ratio = 3;
}
-
- outFile.println("<div class=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 60px;\">");
+
+ outFile.println("<div class=\"box\" style=\"width:" + ratio
+ + "%; top: " + yOffset + "px; left: 60px;\">");
outFile.println("<div id=\"lb\">");
outFile.println("<div id=\"rb\">");
outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -575,63 +593,17 @@
outFile.println("</div></div></div></div>");
outFile.println("</div></div></div></div>");
outFile.println("</div>");
-
- int yOffsetText = yOffset+8;
- outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
- outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:70px;\">"+className+"</div>");
-
- yOffset = yOffset + 25;
-
- }
-
- outFile.println("</div>");
- outFile.println("</body>");
- outFile.println("</html>");
- outFile.close();
- }
- }
- public static void makeDependenciesTableHtmls() throws IOException{
-
- for (String className : GlobalInformation.classToWhatItDependsOn.keySet()){
-
- String outFileName = className + "Deps.html";
- final PrintWriter outFile = new PrintWriter(outFileName);
-
- outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
- outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
- outFile.println("<html>");
- outFile.println("<head>");
- outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
- outFile.println("<title>Classes that \"" + className + "\" depends on</title>");
- outFile.println("</head>");
-
- outFile.println("<style type=\"text/css\">");
- outFile.println("body {background-color: #728FCE}");
- outFile.println("h2 {background-color: transparent}");
- outFile.println("p {background-color: fuchsia}");
- outFile.println("</style>");
-
- outFile.println("<body>");
- outFile.println("<center>");
- outFile.println("<h2>Classes that \"" + className + "\" depends on</h2>");
- outFile.println("</center>");
- outFile.println("<hr>");
-
- outFile.println("<center>");
- outFile.println("<table border=\"1\" width=\"80%\" style=\"font-size: 11pt;\" bgcolor=\"white\">");
-
- for (String depClassName : GlobalInformation.classToWhatItDependsOn.get(className)){
-
- outFile.println("<tr>");
- outFile.println("<td width=\"80%\">" + depClassName + "</td>");
- outFile.println("</tr>");
-
+ int yOffsetText = yOffset + 8;
+ outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:5px;\">%.1f</div>\n", size);
+ outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:70px;\">" + className + "</div>");
+
+ yOffset = yOffset + 25;
+
}
-
- outFile.println("</table>");
- outFile.println("<center>");
-
+
outFile.println("</div>");
outFile.println("</body>");
outFile.println("</html>");
@@ -639,137 +611,68 @@
}
}
- /**
- * Makes html file for fragment classes.
- * TODO(kprobst): update this once we have SOYC updated to supply enough information
- * @throws IOException
- */
- public static void makeFragmentClassesHtmls() throws IOException{
-
-
- for (Integer fragmentName : GlobalInformation.fragmentToStories.keySet()){
- HashSet<String> alreadyPrintedClasses = new HashSet<String>();
-
- String outFileName = "fragment" + Integer.toString(fragmentName) + "Classes.html";
-
- final PrintWriter outFile = new PrintWriter(outFileName);
-
- outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
- outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
- outFile.println("<html>");
- outFile.println("<head>");
- outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
- outFile.println("<title>Classes correlated with fragment " + Integer.toString(fragmentName) + " </title>");
- outFile.println("</head>");
-
- outFile.println("<style type=\"text/css\">");
- outFile.println("body {background-color: #728FCE}");
- outFile.println("h2 {background-color: transparent}");
- outFile.println("p {background-color: fuchsia}");
- outFile.println(".tablediv {");
- outFile.println("display: table;");
- outFile.println("width:100%;");
- outFile.println("background-color:#eee;");
- outFile.println("border:1px solid #666666;");
- outFile.println("border-spacing:5px;");
- outFile.println("border-collapse:separate;");
- outFile.println("}");
- outFile.println(".celldiv {");
- outFile.println("float:left;");
- outFile.println("display: table-cell;");
- outFile.println("width:49.5%;");
- outFile.println("font-size: 14px;");
- outFile.println("background-color:white;");
- outFile.println("}");
- outFile.println(".rowdiv {");
- outFile.println("display: table-row;");
- outFile.println("width:100%;");
- outFile.println("}");
- outFile.println("</style>");
-
- outFile.println("<body>");
- outFile.println("<center>");
- outFile.println("<h2>Classes correlated with fragment " + Integer.toString(fragmentName) + "</h2>");
- outFile.println("</center>");
- outFile.println("<hr>");
-
- outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
- outFile.println("<div class=\"tablediv\">");
-
- for (String storyName : GlobalInformation.fragmentToStories.get(fragmentName)){
- if (GlobalInformation.storiesToCorrClasses.containsKey(storyName)){
- for (String className : GlobalInformation.storiesToCorrClasses.get(storyName)){
-
- if (! alreadyPrintedClasses.contains(className)){
- //outFile.println("<div class=\"rowdiv\">");
- outFile.println("<div class=\"rowdiv\">" + className + "</div>");
- //outFile.println("</div>");
- alreadyPrintedClasses.add(className);
- }
- }
- }
- }
- outFile.println("</div>");
- outFile.println("</body>");
- outFile.println("</html>");
- outFile.close();
- }
- }
+ public static void makeHTMLShell(
+ HashMap<String, CodeCollection> nameToCodeColl,
+ TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
+ // this will contain the place holder iframes where the actual information
+ // is going to go.
- public static void makeHTMLShell(HashMap<String, CodeCollection> nameToCodeColl, TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
- //this will contain the place holder iframes where the actual information is going to go.
-
System.out.println("making html shell");
// copy from the bin directory to the current directory
String classPath = System.getProperty("java.class.path");
- if (!classPath.endsWith("/")){
+ if (!classPath.endsWith("/")) {
classPath += "/";
}
String inputFileName = "roundedCorners.css";
File inputFile = new File(classPath + inputFileName);
File outputFile = new File("roundedCorners.css");
+ System.err.println("now trying to copy inputFile |" + inputFile
+ + "| to outputFile |" + outputFile + "|, classPath is " + classPath
+ + ", inputFileName is: |" + inputFileName);
copyFileOrDirectory(inputFile, outputFile, classPath, inputFileName, false);
inputFileName = "classLevel.css";
File inputFile2 = new File(classPath + inputFileName);
File outputFile2 = new File("classLevel.css");
- copyFileOrDirectory(inputFile2, outputFile2, classPath, inputFileName, false);
-
+ copyFileOrDirectory(inputFile2, outputFile2, classPath, inputFileName,
+ false);
+
inputFileName = "images";
File inputDir = new File(classPath + "images");
File outputDir = new File("images");
copyFileOrDirectory(inputDir, outputDir, classPath, inputFileName, true);
-
-
+
String fileName = "SoycDashboard-index.html";
-
+
final PrintWriter outFile = new PrintWriter(fileName);
outFile.println("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">");
outFile.println("<html>");
outFile.println("<head>");
outFile.println("<title>Story of Your Compile - Top Level Dashboard for Permutation</title>");
-
+
outFile.println("<style type=\"text/css\">");
outFile.println("body {background-color: #728FCE}");
outFile.println("h2 {background-color: transparent}");
outFile.println("p {background-color: fuchsia}");
outFile.println("</style>");
outFile.println("</head>");
-
-
+
outFile.println("<body>");
outFile.println("<center>");
outFile.println("<h3>Story of Your Compile Dashboard</h3>");
outFile.println("<hr>");
- if (GlobalInformation.fragmentToStories.size() > 1){
- outFile.println("<b>Full code size: <span style=\"color:maroon\">" + GlobalInformation.cumSizeAllCode + "</span>, Size of Initial Download: <span style=\"color:maroon\">" + GlobalInformation.fragmentToPartialSize.get(0) + "</span></b>");
+ if (GlobalInformation.fragmentToStories.size() > 1) {
+ outFile.println("<b>Full code size: <span style=\"color:maroon\">"
+ + GlobalInformation.cumSizeAllCode
+ + "</span>, Size of Initial Download: <span style=\"color:maroon\">"
+ + GlobalInformation.fragmentToPartialSize.get(0) + "</span></b>");
+ } else {
+ outFile.println("<b>Full code size: <span style=\"color:maroon\">"
+ + GlobalInformation.cumSizeAllCode + "</span></b>");
}
- else{
- outFile.println("<b>Full code size: <span style=\"color:maroon\">" + GlobalInformation.cumSizeAllCode + "</span></b>");
- }
-
+
outFile.println("<hr>");
-
+
outFile.println("</center>");
outFile.println(" <div style=\"width:50%; float:left; padding-top: 10px;\">");
outFile.println("<b>Package breakdown</b>");
@@ -777,91 +680,84 @@
outFile.println(" <div style=\"width:48%; float:right; padding-top: 10px; \">");
outFile.println("<b>Code type breakdown</b>");
outFile.println(" </div>");
-
-
+
outFile.println(" <div style=\"width:50%; float:left; padding-top: 10px;\">");
outFile.println("<div style=\"width: 110px; float: left; font-size:16px;\">Size</div>");
outFile.println("<div style=\"width: 200px; float: left; text-align:left; font-size:16px; \">Package Name</div>");
outFile.println(" </div>");
-
-
+
outFile.println(" <div style=\"width:48%; float:right; padding-top: 10px;\">");
outFile.println("<div style=\"width: 110px; float: left; font-size:16px;\">Size</div>");
outFile.println("<div style=\"width: 200px; float: left; text-align:left; font-size:16px; \">Code Type</div>");
outFile.println(" </div>");
-
-
-
+
outFile.println("<div style=\"height:35%; width:48%; margin:0 auto; background-color:white; float:left;\">");
outFile.println("<iframe src=\"packageBreakdown.html\" width=100% height=100% scrolling=auto></iframe>");
outFile.println(" </div>");
makePackageHtml("packageBreakdown.html");
-
+
outFile.println("<div style=\"height:35%; width:48%; margin:0 auto; background-color:white; float:right;\">");
outFile.println("<iframe src=\"codeTypeBreakdown.html\" width=100% height=100% scrolling=auto></iframe>");
outFile.println(" </div>");
makeCodeTypeHtml("codeTypeBreakdown.html", nameToCodeColl);
-
+
outFile.println(" <div style=\"width:50%; float:left; padding-top: 10px;\">");
outFile.println("<b>Literals breakdown</b>");
outFile.println(" </div>");
outFile.println(" <div style=\"width:48%; float:right; padding-top: 10px; \">");
outFile.println("<b>String literals breakdown</b>");
outFile.println(" </div>");
-
-
+
outFile.println(" <div style=\"width:50%; float:left; padding-top: 10px;\">");
outFile.println("<div style=\"width: 110px; float: left; font-size:16px;\">Size</div>");
outFile.println("<div style=\"width: 200px; float: left; text-align:left; font-size:16px; \">Literal Type</div>");
outFile.println(" </div>");
-
-
+
outFile.println(" <div style=\"width:48%; float:right; padding-top: 10px; \">");
outFile.println("<div style=\"width: 110px; float: left; font-size:16px;\">Size</div>");
outFile.println("<div style=\"width: 200px; float: left; text-align:left; font-size:16px; \">String Literal Type</div>");
outFile.println(" </div>");
-
-
+
outFile.println("<div style=\"height:35%; width:48%; margin:0 auto; background-color:white; float:left;\">");
outFile.println("<iframe src=\"literalsBreakdown.html\" width=100% height=100% scrolling=auto></iframe>");
outFile.println("</div>");
makeLiteralsHtml("literalsBreakdown.html", nameToLitColl);
-
+
outFile.println("<div style=\"height:35%; width:48%; margin:0 auto; background-color:white; float:right;\">");
outFile.println("<iframe src=\"stringLiteralsBreakdown.html\" width=100% height=100% scrolling=auto></iframe>");
outFile.println(" </div>");
makeStringLiteralsHtml("stringLiteralsBreakdown.html", nameToLitColl);
-
-
- if (GlobalInformation.fragmentToStories.size() > 1){
+
+ if (GlobalInformation.fragmentToStories.size() > 1) {
outFile.println(" <div style=\"width:50%; float:left; padding-top: 10px;\">");
outFile.println("<b>Breakdown by runAsync split points</b>");
outFile.println(" </div>");
-
+
outFile.println(" <div style=\"width:100%; float:left; padding-top: 10px;\">");
outFile.println("<div style=\"width: 110px; float: left; font-size:16px;\">Size</div>");
outFile.println("<div style=\"width: 200px; float: left; text-align:left; font-size:16px; \">Fragment Name</div>");
outFile.println(" </div>");
-
+
outFile.println("<div style=\"height:35%; width:100%; margin:0 auto; background-color:white; float:left;\">");
outFile.println("<iframe src=\"fragmentsBreakdown.html\" width=100% height=100% scrolling=auto></iframe>");
outFile.println("</div>");
makeFragmentsHtml("fragmentsBreakdown.html");
}
-
+
outFile.println(" </body>");
outFile.println("</html>");
outFile.close();
-
+
}
- public static void makeLiteralsClassesTableHtmls(TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
+ public static void makeLiteralsClassesTableHtmls(
+ TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
- for (String literalType : nameToLitColl.keySet()){
-
+ for (String literalType : nameToLitColl.keySet()) {
+
String outFileName = literalType + "Lits.html";
final PrintWriter outFile = new PrintWriter(outFileName);
-
+
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
@@ -875,101 +771,99 @@
outFile.println("h2 {background-color: transparent}");
outFile.println("p {background-color: fuchsia}");
outFile.println("</style>");
-
+
outFile.println("<body>");
outFile.println("<center>");
outFile.println("<h2>Literals of type \"" + literalType + "\"</h2>");
outFile.println("</center>");
outFile.println("<hr>");
-
+
outFile.println("<center>");
outFile.println("<table border=\"1\" width=\"80%\" style=\"font-size: 11pt;\" bgcolor=\"white\">");
-
- for (String literal : nameToLitColl.get(literalType).literalToLocations.keySet()){
-
- if (literal.trim().compareTo("") == 0){
+
+ for (String literal : nameToLitColl.get(literalType).literalToLocations.keySet()) {
+
+ if (literal.trim().compareTo("") == 0) {
literal = "[whitespace only string]";
}
-
String newLiteral = "";
- if(literal.length() > 80){
+ if (literal.length() > 80) {
int i;
- for (i = 80; i < literal.length(); i=i+80){
- String part1 = literal.substring(i-80, i);
- newLiteral = newLiteral + part1 + " ";
+ for (i = 80; i < literal.length(); i = i + 80) {
+ String part1 = literal.substring(i - 80, i);
+ newLiteral = newLiteral + part1 + " ";
}
- if (i-80 > 0){
- newLiteral = newLiteral + literal.substring(i-80);
+ if (i - 80 > 0) {
+ newLiteral = newLiteral + literal.substring(i - 80);
}
- }
- else{
+ } else {
newLiteral = literal;
}
-
+
String escliteral = escapeXml(newLiteral);
outFile.println("<tr>");
outFile.println("<td width=\"40%\">" + escliteral + "</td>");
-
int ct = 0;
- for (String location : nameToLitColl.get(literalType).literalToLocations.get(literal)){
-
- if (ct > 0){
- outFile.println("<tr>");
- outFile.println("<td width=\"40%\"> </td>");
- }
-
- String newLocation = "";
- if(location.length() > 80){
- int i;
- for (i = 80; i < location.length(); i=i+80){
- String part1 = location.substring(i-80, i);
- newLocation = newLocation + part1 + " ";
- }
- if (i-80 > 0){
- newLocation = newLocation + location.substring(i-80);
- }
- }
- else{
- newLocation = location;
- }
-
-
- outFile.println("<td width=\"40%\">" + newLocation + "</td>");
+ if ((nameToLitColl.containsKey(literalType))
+ && (nameToLitColl.get(literalType).literalToLocations.containsKey(literal))) {
+ for (String location : nameToLitColl.get(literalType).literalToLocations.get(literal)) {
- if (ct > 0){
- outFile.println("</tr>");
+ if (ct > 0) {
+ outFile.println("<tr>");
+ outFile.println("<td width=\"40%\"> </td>");
+ }
+
+ String newLocation = "";
+ if (location.length() > 80) {
+ int i;
+ for (i = 80; i < location.length(); i = i + 80) {
+ String part1 = location.substring(i - 80, i);
+ newLocation = newLocation + part1 + " ";
+ }
+ if (i - 80 > 0) {
+ newLocation = newLocation + location.substring(i - 80);
+ }
+ } else {
+ newLocation = location;
+ }
+
+ outFile.println("<td width=\"40%\">" + newLocation + "</td>");
+
+ if (ct > 0) {
+ outFile.println("</tr>");
+ }
+ ct++;
}
- ct++;
-
+ } else {
+ System.err.println("either literalType " + literalType
+ + " not known, or no location for literal " + literal);
}
-
outFile.println("</tr>");
-
+
}
outFile.println("</table>");
outFile.println("<center>");
-
outFile.println("</div>");
outFile.println("</body>");
outFile.println("</html>");
outFile.close();
- }
+ }
}
- public static void makeLiteralsClassesHtmls(TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
-
-
- for (String literalType : nameToLitColl.keySet()){
-
+ public static void makeLiteralsClassesHtmls(
+ TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
+
+ for (String literalType : nameToLitColl.keySet()) {
+
String outFileName = literalType + "Lits.html";
final PrintWriter outFile = new PrintWriter(outFileName);
-
+
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
@@ -999,61 +893,57 @@
outFile.println("}");
outFile.println(".rowdiv {");
outFile.println("display: table-row;");
- //outFile.println("width:90%;");
outFile.println("}");
outFile.println("</style>");
-
+
outFile.println("<body>");
outFile.println("<center>");
outFile.println("<h2>Literals of type \"" + literalType + "\"</h2>");
outFile.println("</center>");
outFile.println("<hr>");
-
- outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
- outFile.println("<div class=\"tablediv\">");
- for (String literal : nameToLitColl.get(literalType).literalToLocations.keySet()){
-
- if (literal.trim().compareTo("") == 0){
+
+ outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
+ outFile.println("<div class=\"tablediv\">");
+ for (String literal : nameToLitColl.get(literalType).literalToLocations.keySet()) {
+
+ if (literal.trim().compareTo("") == 0) {
literal = "[whitespace only string]";
}
-
String newLiteral = "";
- if(literal.length() > 100){
+ if (literal.length() > 100) {
int i;
- for (i = 100; i < literal.length(); i=i+100){
- String part1 = literal.substring(i-100, i);
- newLiteral = newLiteral + part1 + " ";
+ for (i = 100; i < literal.length(); i = i + 100) {
+ String part1 = literal.substring(i - 100, i);
+ newLiteral = newLiteral + part1 + " ";
}
- if (i-100 > 0){
- newLiteral = newLiteral + literal.substring(i-100);
+ if (i - 100 > 0) {
+ newLiteral = newLiteral + literal.substring(i - 100);
}
- }
- else{
+ } else {
newLiteral = literal;
}
-
+
String escliteral = escapeXml(newLiteral);
- outFile.println("<div class=\"rowdiv\">");
+ outFile.println("<div class=\"rowdiv\">");
outFile.println("<div class=\"celldiv\">" + escliteral + "</div>");
- for (String location : nameToLitColl.get(literalType).literalToLocations.get(literal)){
-
+ for (String location : nameToLitColl.get(literalType).literalToLocations.get(literal)) {
+
String newLocation = "";
- if(location.length() > 100){
+ if (location.length() > 100) {
int i;
- for (i = 100; i < location.length(); i=i+100){
- String part1 = location.substring(i-100, i);
- newLocation = newLocation + part1 + " ";
+ for (i = 100; i < location.length(); i = i + 100) {
+ String part1 = location.substring(i - 100, i);
+ newLocation = newLocation + part1 + " ";
}
- if (i-100 > 0){
- newLocation = newLocation + location.substring(i-100);
+ if (i - 100 > 0) {
+ newLocation = newLocation + location.substring(i - 100);
}
- }
- else{
+ } else {
newLocation = location;
}
-
+
outFile.println("<div class=\"celldiv\">" + newLocation + "</div>");
}
outFile.println("</div>");
@@ -1062,96 +952,94 @@
outFile.println("</body>");
outFile.println("</html>");
outFile.close();
- }
+ }
}
- public static void makePackageClassesHtmls() throws IOException{
-
- for (String packageName : GlobalInformation.packageToClasses.keySet()){
-
+ public static void makePackageClassesHtmls() throws IOException {
+
+ for (String packageName : GlobalInformation.packageToClasses.keySet()) {
+
String outFileName = packageName + "Classes.html";
- TreeMap<Float, String> sortedClasses = new TreeMap<Float, String>(Collections.reverseOrder());
+ TreeMap<Float, String> sortedClasses = new TreeMap<Float, String>(
+ Collections.reverseOrder());
float maxSize = 0f;
-
- //TODO(kprobst): not currently used, but will be for dependencies
+
int maxDepCount = 1;
-
- for (String className : GlobalInformation.packageToClasses.get(packageName)){
-
+
+ for (String className : GlobalInformation.packageToClasses.get(packageName)) {
+
float curSize = 0f;
- if (! GlobalInformation.classToPartialSize.containsKey(className)){
- System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className + " *****");
- }
- else{
+ if (!GlobalInformation.classToPartialSize.containsKey(className)) {
+ System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className
+ + " *****");
+ } else {
curSize = GlobalInformation.classToPartialSize.get(className);
}
-
- //TODO(kprobst): not currently used, but will be for dependencies
+
int depCount = 0;
- if (GlobalInformation.classToWhatItDependsOn.containsKey(className)){
+ if (GlobalInformation.classToWhatItDependsOn.containsKey(className)) {
depCount = GlobalInformation.classToWhatItDependsOn.get(className).size();
}
-
- if (curSize != 0f){
-
+
+ if (curSize != 0f) {
+
sortedClasses.put(curSize, className);
- if (curSize > maxSize){
+ if (curSize > maxSize) {
maxSize = curSize;
}
- //TODO(kprobst): not currently used, but will be for dependencies
- if (depCount > maxDepCount){
+ if (depCount > maxDepCount) {
maxDepCount = depCount;
}
}
}
-
-
+
final PrintWriter outFile = new PrintWriter(outFileName);
-
+
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
outFile.println("<head>");
outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
outFile.println("<link rel=\"stylesheet\" href=\"classLevel.css\" media=\"screen\">");
- outFile.println("<title>Classes in package \"" + packageName + "\"</title>");
+ outFile.println("<title>Classes in package \"" + packageName
+ + "\"</title>");
outFile.println("</head>");
outFile.println("<body>");
-
-
+
outFile.println("<center>");
outFile.println("<h2>Classes in package \"" + packageName + "\"</h2>");
outFile.println("</center>");
outFile.println("<hr>");
-
+
outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 90px; left:70px; position:absolute; background-color:white\"");
-
-
+
int yOffset = 0;
- for (Float size : sortedClasses.keySet()){
-
+ for (Float size : sortedClasses.keySet()) {
+
String className = sortedClasses.get(size);
-
- //TODO(kprobst): switch out the commented/uncommented lines below when showing dependencies
+
+ // TODO(kprobst): switch out the commented/uncommented lines below when
+ // showing dependencies
// float ratio = (size / maxSize) * 45;
float ratio = (size / maxSize) * 85;
-
- if (ratio < 3){
+
+ if (ratio < 3) {
ratio = 3;
}
-
- //TODO(kprobst): not currently used, but will be for dependencies
- // get the dependency count
+
+ // TODO(kprobst): not currently used, but will be for dependencies
+ // get the dependency count
int depCount = 0;
- if (GlobalInformation.classToWhatItDependsOn.containsKey(className)){
+ if (GlobalInformation.classToWhatItDependsOn.containsKey(className)) {
depCount = GlobalInformation.classToWhatItDependsOn.get(className).size();
}
- float depRatio = ((float)depCount / (float)maxDepCount) * 45f;
- if (depRatio < 3.0){
+ float depRatio = ((float) depCount / (float) maxDepCount) * 45f;
+ if (depRatio < 3.0) {
depRatio = 3;
}
-
- outFile.println("<div class=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 60px;\">");
+
+ outFile.println("<div class=\"box\" style=\"width:" + ratio
+ + "%; top: " + yOffset + "px; left: 60px;\">");
outFile.println("<div id=\"lb\">");
outFile.println("<div id=\"rb\">");
outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -1161,32 +1049,42 @@
outFile.println("</div></div></div></div>");
outFile.println("</div></div></div></div>");
outFile.println("</div>");
-
-
- //TODO(kprobst): not currently used, but will be for dependencies
-/* outFile.println("<div class=\"box-right\" style=\"width:" + depRatio + "%; top: " + yOffset + "px; left: 50%\">");
- outFile.println("<div id=\"lb\">");
- outFile.println("<div id=\"rb\">");
- outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
- outFile.println("<div id=\"tb\"><div id=\"tlc\"><div id=\"trc\">");
- outFile.println("<div id=\"content\">");
- outFile.println("</div>");
- outFile.println("</div></div></div></div>");
- outFile.println("</div></div></div></div>");
- outFile.println("</div>");*/
-
- int yOffsetText = yOffset+8;
- outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
- outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:70px;\">"+className+"</div>");
-
-/* //TODO(kprobst) make this a link
- String drillDownFileName = className + "Deps.html";
- outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:50%;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">Dependencies: " + depCount + "</a></div>");
-*/
+
+ // TODO(kprobst): not currently used, but will be for dependencies
+ /*
+ * outFile.println("<div class=\"box-right\" style=\"width:" + depRatio
+ * + "%; top: " + yOffset + "px; left: 50%\">");
+ * outFile.println("<div id=\"lb\">");
+ * outFile.println("<div id=\"rb\">");
+ * outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
+ * outFile.println("<div id=\"tb\"><div id=\"tlc\"><div id=\"trc\">");
+ * outFile.println("<div id=\"content\">"); outFile.println("</div>");
+ * outFile.println("</div></div></div></div>");
+ * outFile.println("</div></div></div></div>");
+ * outFile.println("</div>");
+ */
+
+ int yOffsetText = yOffset + 8;
+ outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:5px;\">%.1f</div>\n", size);
+ if (GlobalInformation.displayDependencies == true) {
+ outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:70px;\"><a href=\"methodDependencies-" + packageName
+ + ".html#" + className + "\">" + className + "</a></div>");
+ } else {
+ outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+ + "px; left:70px;\">" + className + "</div>");
+ }
+ /*
+ * //TODO(kprobst) make this a link String drillDownFileName = className
+ * + "Deps.html"; outFile.println("<div class=\"barlabel\" style=\"top:"
+ * + yOffsetText + "px; left:50%;\"><a href=\"" + drillDownFileName +
+ * "\" target=\"_top\">Dependencies: " + depCount + "</a></div>");
+ */
yOffset = yOffset + 25;
-
+
}
-
+
outFile.println("</div>");
outFile.println("</body>");
outFile.println("</html>");
@@ -1195,53 +1093,58 @@
}
/**
- * Makes html file for fragment classes.
- * TODO(kprobst): update this once we have SOYC updated to supply enough information
+ * Makes html file for fragment classes. TODO(kprobst): update this once we
+ * have SOYC updated to supply enough information
+ *
* @throws IOException
*/
- public static void makeSplitPointClassesHtmls() throws IOException{
-
- //for the initial fragment and the fragments in the load order, we can print this immediately
- // For those fragments *not* in the initial load order, we just collect and then print at the end
+ public static void makeSplitPointClassesHtmls() throws IOException {
+
+ // for the initial fragment and the fragments in the load order, we can
+ // print this immediately
+ // For those fragments *not* in the initial load order, we just collect and
+ // then print at the end
TreeSet<String> sortedClassesAndMethodsAllOtherFragments = new TreeSet<String>();
-
- for (Integer fragmentName : GlobalInformation.fragmentToStories.keySet()){
-
- if ((fragmentName != 0)&&(!GlobalInformation.splitPointToLocation.containsKey(fragmentName))){
-
+
+ for (Integer fragmentName : GlobalInformation.fragmentToStories.keySet()) {
+
+ if ((fragmentName != 0)
+ && (!GlobalInformation.splitPointToLocation.containsKey(fragmentName))) {
+
// get the stories from ALL the fragments
- for (String storyName : GlobalInformation.fragmentToStories.get(fragmentName)){
- if ((!GlobalInformation.nameToLitColl.get("string").storyToLocations.containsKey(storyName))&&(GlobalInformation.storiesToCorrClassesAndMethods.containsKey(storyName))){
- for (String className : GlobalInformation.storiesToCorrClassesAndMethods.get(storyName)){
- sortedClassesAndMethodsAllOtherFragments.add(className);
+ for (String storyName : GlobalInformation.fragmentToStories.get(fragmentName)) {
+ if ((!GlobalInformation.nameToLitColl.get("string").storyToLocations.containsKey(storyName))
+ && (GlobalInformation.storiesToCorrClassesAndMethods.containsKey(storyName))) {
+ for (String className : GlobalInformation.storiesToCorrClassesAndMethods.get(storyName)) {
+ sortedClassesAndMethodsAllOtherFragments.add(className);
}
}
}
}
-
-// else if ((fragmentName == 0)||(GlobalInformation.splitPointToLocation.containsKey(fragmentName))){
- else{
+
+ else {
String curSplitPointLocation;
-
- if (fragmentName == 0){
+
+ if (fragmentName == 0) {
curSplitPointLocation = "initialDownload";
- }
- else{
+ } else {
curSplitPointLocation = GlobalInformation.splitPointToLocation.get(fragmentName);
}
-
- String outFileName = "splitPoint" + curSplitPointLocation + "Classes.html";
-
+
+ String outFileName = "splitPoint" + curSplitPointLocation
+ + "Classes.html";
+
final PrintWriter outFile = new PrintWriter(outFileName);
-
+
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
outFile.println("<head>");
outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
- outFile.println("<title>Classes and methods in exclusives fragment for runAsync split point \"" + curSplitPointLocation + "\" </title>");
+ outFile.println("<title>Classes and methods in exclusives fragment for runAsync split point \""
+ + curSplitPointLocation + "\" </title>");
outFile.println("</head>");
-
+
outFile.println("<style type=\"text/css\">");
outFile.println("body {background-color: #728FCE}");
outFile.println("h2 {background-color: transparent}");
@@ -1266,57 +1169,62 @@
outFile.println("width:100%;");
outFile.println("}");
outFile.println("</style>");
-
+
outFile.println("<body>");
outFile.println("<center>");
- outFile.println("<h2>Classes and methods in exclusives fragment for runAsync split point \"" + curSplitPointLocation + "\"</h2>");
+ outFile.println("<h2>Classes and methods in exclusives fragment for runAsync split point \""
+ + curSplitPointLocation + "\"</h2>");
outFile.println("</center>");
outFile.println("<hr>");
-
- outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
- outFile.println("<div class=\"tablediv\">");
-
+
+ outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
+ outFile.println("<div class=\"tablediv\">");
+
TreeSet<String> sortedClassesAndMethods = new TreeSet<String>();
- for (String storyName : GlobalInformation.fragmentToStories.get(fragmentName)){
- if ((!GlobalInformation.nameToLitColl.get("string").storyToLocations.containsKey(storyName))&&(GlobalInformation.storiesToCorrClassesAndMethods.containsKey(storyName))){
- for (String className : GlobalInformation.storiesToCorrClassesAndMethods.get(storyName)){
- sortedClassesAndMethods.add(className);
+ for (String storyName : GlobalInformation.fragmentToStories.get(fragmentName)) {
+ if ((!GlobalInformation.nameToLitColl.get("string").storyToLocations.containsKey(storyName))
+ && (GlobalInformation.storiesToCorrClassesAndMethods.containsKey(storyName))) {
+ for (String className : GlobalInformation.storiesToCorrClassesAndMethods.get(storyName)) {
+ sortedClassesAndMethods.add(className);
}
}
}
- for (String classOrMethod : sortedClassesAndMethods){
+ for (String classOrMethod : sortedClassesAndMethods) {
-
- //if it's a method
- if ((GlobalInformation.displayDependencies == true)&&(classOrMethod.contains("("))&&(classOrMethod.contains(")"))){
- //get the package
+ // if it's a method
+ if ((GlobalInformation.displayDependencies == true)
+ && (classOrMethod.contains("(")) && (classOrMethod.contains(")"))) {
+ // get the package
String packageName = classOrMethod;
packageName = packageName.replaceAll("\\.\\p{Upper}.*", "");
-
+
String noParamMethod = classOrMethod;
noParamMethod = noParamMethod.replaceAll("\\(.*", "");
-
- outFile.println("<div class=\"rowdiv\"><a href=\"methodDependencies-" + packageName + ".html#"+ noParamMethod + "\">" + classOrMethod + "</a></div>");
- }
- else{
- outFile.println("<div class=\"rowdiv\">" + classOrMethod + "</div>");
+
+ outFile.println("<div class=\"rowdiv\"><a href=\"methodDependencies-"
+ + packageName
+ + ".html#"
+ + noParamMethod
+ + "\">"
+ + classOrMethod + "</a></div>");
+ } else {
+ outFile.println("<div class=\"rowdiv\">" + classOrMethod
+ + "</div>");
}
}
-
+
outFile.println("</div>");
outFile.println("</body>");
outFile.println("</html>");
outFile.close();
- }
+ }
}
-
-
- //finally, make the file for all the other fragments
+
+ // finally, make the file for all the other fragments
String outFileName = "splitPointAllOtherFragmentsClasses.html";
-
+
final PrintWriter outFile = new PrintWriter(outFileName);
-
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
@@ -1349,53 +1257,52 @@
outFile.println("width:100%;");
outFile.println("}");
outFile.println("</style>");
-
+
outFile.println("<body>");
outFile.println("<center>");
outFile.println("<h2>Classes and methods in exclusives fragment for runAsync split point \"allOtherFragments\"</h2>");
outFile.println("</center>");
outFile.println("<hr>");
-
- outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
- outFile.println("<div class=\"tablediv\">");
-
- for (String classOrMethod : sortedClassesAndMethodsAllOtherFragments){
- //if it's a method
- if ((GlobalInformation.displayDependencies == true)&&(classOrMethod.contains("("))&&(classOrMethod.contains(")"))){
- //get the package
+ outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
+ outFile.println("<div class=\"tablediv\">");
+
+ for (String classOrMethod : sortedClassesAndMethodsAllOtherFragments) {
+
+ // if it's a method
+ if ((GlobalInformation.displayDependencies == true)
+ && (classOrMethod.contains("(")) && (classOrMethod.contains(")"))) {
+ // get the package
String packageName = classOrMethod;
packageName = packageName.replaceAll("\\.\\p{Upper}.*", "");
-
+
String noParamMethod = classOrMethod;
noParamMethod = noParamMethod.replaceAll("\\(.*", "");
-
- outFile.println("<div class=\"rowdiv\"><a href=\"methodDependencies-" + packageName + ".html#"+ noParamMethod + "\">" + classOrMethod + "</a></div>");
- }
- else{
+
+ outFile.println("<div class=\"rowdiv\"><a href=\"methodDependencies-"
+ + packageName + ".html#" + noParamMethod + "\">" + classOrMethod
+ + "</a></div>");
+ } else {
outFile.println("<div class=\"rowdiv\">" + classOrMethod + "</div>");
}
}
-
+
outFile.println("</div>");
outFile.println("</body>");
outFile.println("</html>");
outFile.close();
-
-
}
- public static void makeStringLiteralsClassesHtmls(TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
-
-
- for (String literalType : nameToLitColl.get("string").stringTypeToSize.keySet()){
-
+ public static void makeStringLiteralsClassesHtmls(
+ TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
+
+ for (String literalType : nameToLitColl.get("string").stringTypeToSize.keySet()) {
+
String outFileName = literalType + "Strings.html";
-
+
final PrintWriter outFile = new PrintWriter(outFileName);
-
-
+
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
@@ -1428,62 +1335,59 @@
outFile.println("width:100%;");
outFile.println("}");
outFile.println("</style>");
-
+
outFile.println("<body>");
outFile.println("<center>");
outFile.println("<h2>Literals of type \"" + literalType + "\"</h2>");
outFile.println("</center>");
outFile.println("<hr>");
-
- outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
- outFile.println("<div class=\"tablediv\">");
-
- for (String literal : nameToLitColl.get("string").stringLiteralToType.keySet()){
-
- if (nameToLitColl.get("string").stringLiteralToType.get(literal).compareTo(literalType) == 0){
-
+ outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
+ outFile.println("<div class=\"tablediv\">");
- if (literal.trim().compareTo("") == 0){
+ for (String literal : nameToLitColl.get("string").stringLiteralToType.keySet()) {
+
+ if (nameToLitColl.get("string").stringLiteralToType.get(literal).compareTo(
+ literalType) == 0) {
+
+ if (literal.trim().compareTo("") == 0) {
literal = "[whitespace only string]";
}
-
+
String newLiteral = "";
- if(literal.length() > 100){
+ if (literal.length() > 100) {
int i;
- for (i = 100; i < literal.length(); i=i+100){
- String part1 = literal.substring(i-100, i);
- newLiteral = newLiteral + part1 + " ";
+ for (i = 100; i < literal.length(); i = i + 100) {
+ String part1 = literal.substring(i - 100, i);
+ newLiteral = newLiteral + part1 + " ";
}
- if (i-100 > 0){
- newLiteral = newLiteral + literal.substring(i-100);
+ if (i - 100 > 0) {
+ newLiteral = newLiteral + literal.substring(i - 100);
}
- }
- else{
+ } else {
newLiteral = literal;
}
-
+
String escliteral = escapeXml(newLiteral);
- outFile.println("<div class=\"rowdiv\">");
+ outFile.println("<div class=\"rowdiv\">");
outFile.println("<div class=\"celldiv\">" + escliteral + "</div>");
- for (String location : nameToLitColl.get("string").literalToLocations.get(literal)){
-
+ for (String location : nameToLitColl.get("string").literalToLocations.get(literal)) {
+
String newLocation = "";
- if(location.length() > 100){
+ if (location.length() > 100) {
int i;
- for (i = 100; i < location.length(); i=i+100){
- String part1 = location.substring(i-100, i);
- newLocation = newLocation + part1 + " ";
+ for (i = 100; i < location.length(); i = i + 100) {
+ String part1 = location.substring(i - 100, i);
+ newLocation = newLocation + part1 + " ";
}
- if (i-100 > 0){
- newLocation = newLocation + location.substring(i-100);
+ if (i - 100 > 0) {
+ newLocation = newLocation + location.substring(i - 100);
}
- }
- else{
+ } else {
newLocation = location;
}
-
+
outFile.println("<div class=\"celldiv\">" + newLocation + "</div>");
}
outFile.println("</div>");
@@ -1493,21 +1397,18 @@
outFile.println("</body>");
outFile.println("</html>");
outFile.close();
- }
-
-
+ }
}
-
- public static void makeStringLiteralsClassesTableHtmls(TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
-
- for (String literalType : nameToLitColl.get("string").stringTypeToSize.keySet()){
-
-
+ public static void makeStringLiteralsClassesTableHtmls(
+ TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
+
+ for (String literalType : nameToLitColl.get("string").stringTypeToSize.keySet()) {
+
String outFileName = literalType + "Strings.html";
final PrintWriter outFile = new PrintWriter(outFileName);
-
+
outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
outFile.println("<html>");
@@ -1521,86 +1422,87 @@
outFile.println("h2 {background-color: transparent}");
outFile.println("p {background-color: fuchsia}");
outFile.println("</style>");
-
+
outFile.println("<body>");
outFile.println("<center>");
outFile.println("<h2>Literals of type \"" + literalType + "\"</h2>");
outFile.println("</center>");
outFile.println("<hr>");
-
- outFile.println("<center>");
+
+ outFile.println("<center>");
outFile.println("<table border=\"1\" width=\"80%\" style=\"font-size: 11pt;\" bgcolor=\"white\">");
-
-
-
- for (String literal : nameToLitColl.get("string").stringLiteralToType.keySet()){
-
- if (nameToLitColl.get("string").stringLiteralToType.get(literal).compareTo(literalType) == 0){
-
- if (literal.trim().compareTo("") == 0){
+
+ for (String literal : nameToLitColl.get("string").stringLiteralToType.keySet()) {
+
+ if (nameToLitColl.get("string").stringLiteralToType.get(literal).compareTo(
+ literalType) == 0) {
+
+ if (literal.trim().compareTo("") == 0) {
literal = "[whitespace only string]";
}
-
+
String newLiteral = "";
- if(literal.length() > 80){
+ if (literal.length() > 80) {
int i;
- for (i = 80; i < literal.length(); i=i+80){
- String part1 = literal.substring(i-80, i);
- newLiteral = newLiteral + part1 + " ";
+ for (i = 80; i < literal.length(); i = i + 80) {
+ String part1 = literal.substring(i - 80, i);
+ newLiteral = newLiteral + part1 + " ";
}
- if (i-80 > 0){
- newLiteral = newLiteral + literal.substring(i-80);
+ if (i - 80 > 0) {
+ newLiteral = newLiteral + literal.substring(i - 80);
}
- }
- else{
+ } else {
newLiteral = literal;
}
-
+
String escliteral = escapeXml(newLiteral);
-
+
outFile.println("<tr>");
outFile.println("<td width=\"40%\">" + escliteral + "</td>");
-
-
+
int ct = 0;
- for (String location : nameToLitColl.get("string").literalToLocations.get(literal)){
-
- if (ct > 0){
- outFile.println("<tr>");
- outFile.println("<td width=\"40%\"> </td>");
- }
-
- String newLocation = "";
- if(location.length() > 80){
- int i;
- for (i = 80; i < location.length(); i=i+80){
- String part1 = location.substring(i-80, i);
- newLocation = newLocation + part1 + " ";
+ if (nameToLitColl.get("string").literalToLocations.containsKey(literal)) {
+
+ for (String location : nameToLitColl.get("string").literalToLocations.get(literal)) {
+
+ if (ct > 0) {
+ outFile.println("<tr>");
+ outFile.println("<td width=\"40%\"> </td>");
}
- if (i-80 > 0){
- newLocation = newLocation + location.substring(i-80);
+
+ String newLocation = "";
+ if (location.length() > 80) {
+ int i;
+ for (i = 80; i < location.length(); i = i + 80) {
+ String part1 = location.substring(i - 80, i);
+ newLocation = newLocation + part1 + " ";
+ }
+ if (i - 80 > 0) {
+ newLocation = newLocation + location.substring(i - 80);
+ }
+ } else {
+ newLocation = location;
}
+
+ outFile.println("<td width=\"40%\">" + newLocation + "</td>");
+
+ if (ct > 0) {
+ outFile.println("</tr>");
+ }
+ ct++;
}
- else{
- newLocation = location;
- }
-
-
- outFile.println("<td width=\"40%\">" + newLocation + "</td>");
-
- if (ct > 0){
- outFile.println("</tr>");
- }
- ct++;
+ } else {
+ System.err.println("no location given for string literal: "
+ + literal);
}
outFile.println("</tr>");
- }
+ }
}
outFile.println("</table>");
outFile.println("<center>");
-
+
outFile.println("</div>");
outFile.println("</body>");
outFile.println("</html>");
@@ -1608,75 +1510,92 @@
}
}
-
-
- public static void makeDependenciesHtml(Map<String, ArrayList<String>> dependencies) throws IOException{
+ public static void makeDependenciesHtml(
+ Map<String, ArrayList<String>> dependencies) throws IOException {
String origOutFileName = "methodDependencies-";
PrintWriter outFile = null;
String curPackageName = "";
-
- for (String method : dependencies.keySet()){
+ String curClassName = "";
+
+ for (String method : dependencies.keySet()) {
// this key set is already in alphabetical order
// get the package of this method, i.e., everything up to .[A-Z]
-
+
String packageName = method;
packageName = packageName.replaceAll("\\.\\p{Upper}.*", "");
-
- if ((curPackageName.compareTo("") == 0) || (curPackageName.compareTo(packageName) != 0)){
+ String className = method;
+ className = className.replaceAll("::.*", "");
- curPackageName = packageName;
- if (outFile != null){
- //finish up the current file
- outFile.println("</table>");
- outFile.println("<center>");
-
- outFile.println("</div>");
- outFile.println("</body>");
- outFile.println("</html>");
- outFile.close();
- }
-
- String outFileName = origOutFileName + curPackageName + ".html";
- outFile = new PrintWriter(outFileName);
-
- outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
- outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
- outFile.println("<html>");
- outFile.println("<head>");
- outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
- outFile.println("<title>Method Dependencies</title>");
- outFile.println("</head>");
-
- outFile.println("<style type=\"text/css\">");
- outFile.println("body {background-color: #728FCE}");
- outFile.println("h2 {background-color: transparent}");
- outFile.println("p {background-color: fuchsia}");
- outFile.println("</style>");
-
- outFile.println("<body>");
+ if ((curPackageName.compareTo("") == 0)
+ || (curPackageName.compareTo(packageName) != 0)) {
+
+ curPackageName = packageName;
+ if (outFile != null) {
+ // finish up the current file
+ outFile.println("</table>");
outFile.println("<center>");
- outFile.println("<h2>Method Dependencies</h2>");
- outFile.println("</center>");
- outFile.println("<hr>");
-
- outFile.println("<center>");
- outFile.println("<table border=\"1\" width=\"80%\" style=\"font-size: 11pt;\" bgcolor=\"white\">");
-
+
+ outFile.println("</div>");
+ outFile.println("</body>");
+ outFile.println("</html>");
+ outFile.close();
}
+
+ String outFileName = origOutFileName + curPackageName + ".html";
+ outFile = new PrintWriter(outFileName);
+
+ outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
+ outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
+ outFile.println("<html>");
+ outFile.println("<head>");
+ outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
+ outFile.println("<title>Method Dependencies</title>");
+ outFile.println("</head>");
+
+ outFile.println("<style type=\"text/css\">");
+ outFile.println("body {background-color: #728FCE}");
+ outFile.println("h2 {background-color: transparent}");
+ outFile.println("p {background-color: fuchsia}");
+ outFile.println("</style>");
+
+ outFile.println("<body>");
+ outFile.println("<center>");
+ outFile.println("<h2>Method Dependencies for package " + curPackageName
+ + "</h2>");
+ outFile.println("</center>");
+ outFile.println("<hr>");
+
+ outFile.println("<center>");
+ outFile.println("<table border=\"1\" width=\"80%\" style=\"font-size: 11pt;\" bgcolor=\"white\">");
+
+ }
+ outFile.println("<tr>");
+ if (curClassName.compareTo(className) != 0) {
+ outFile.println("<td width=\"80%\"><a name=\"" + className + "\">"
+ + "<a name=\"" + method + "\">" + method
+ + "</a></a><font color=\"green\"> called by</font></td>");
+ curClassName = className;
+ } else {
+ outFile.println("<td width=\"80%\"><a name=\"" + method + "\">"
+ + method + "</a><font color=\"green\"> called by</font></td>");
+ }
+ outFile.println("</tr>");
+
+ for (int i = 0; i < dependencies.get(method).size(); i++) {
+ String depMethod = dependencies.get(method).get(i);
+
outFile.println("<tr>");
- outFile.println("<td width=\"80%\"><a name=\"" + method + "\">" + method + "</a></td>");
- outFile.println("</tr>");
-
- for (int i = 0; i < dependencies.get(method).size(); i++){
- String depMethod = dependencies.get(method).get(i);
-
- outFile.println("<tr>");
- outFile.println("<td width=\"20%\"></td>");
+ outFile.println("<td width=\"20%\"></td>");
+ if (i != dependencies.get(method).size() - 1) {
+ outFile.println("<td width=\"60%\">" + depMethod
+ + "<font color=\"green\"> called by</font></td>");
+ } else {
outFile.println("<td width=\"60%\">" + depMethod + "</td>");
- outFile.println("</tr>");
}
+ outFile.println("</tr>");
+ }
}
}
}
diff --git a/tools/soyc-vis/src/com/google/gwt/soyc/SoycDashboard.java b/tools/soyc-vis/src/com/google/gwt/soyc/SoycDashboard.java
index 4afe351..2d060fd 100644
--- a/tools/soyc-vis/src/com/google/gwt/soyc/SoycDashboard.java
+++ b/tools/soyc-vis/src/com/google/gwt/soyc/SoycDashboard.java
@@ -31,53 +31,59 @@
import javax.xml.parsers.*;
public class SoycDashboard {
-
+
/**
* @param args Input: XML file containing soyc compile output
- * @throws IOException
- * @throws SAXException
+ * @throws IOException
+ * @throws SAXException
*/
public static void main(String[] args) {
-
- String inFileName = "";
- String depInFileName = "";
- if ((args.length != 1) && (args.length != 2)){
- if (args.length == 1){
+ String storiesFileName = "";
+ String depFileName = "";
+ String splitPointsFileName = "";
+ if ((args.length == 1) || (args.length == 2) || (args.length == 3)) {
+
+ if (args.length == 1) {
GlobalInformation.displayDependencies = false;
- }
- else{
+ GlobalInformation.displaySplitPoints = true;
+ } else if (args.length == 2) {
GlobalInformation.displayDependencies = true;
- depInFileName = args[1];
+ GlobalInformation.displaySplitPoints = false;
+ depFileName = args[1];
+ } else if (args.length == 3) {
+ GlobalInformation.displayDependencies = true;
+ GlobalInformation.displaySplitPoints = true;
+ depFileName = args[1];
+ splitPointsFileName = args[2];
}
- System.err.println("Usage: java com/google/gwt/soyc/SoycDashboard soyc-report0.xml[.gz] soyc-dependencies0.xml[.gz] OR java com/google/gwt/soyc/SoycDashboard soyc-report0.xml[.gz]");
+ } else {
+ System.err.println("Usage: java com/google/gwt/soyc/SoycDashboard soyc-report0.xml[.gz] [soyc-dependencies0.xml[.gz]] [soyc-splitpoints0.xml[.gz]]");
System.exit(1);
}
-
- inFileName = args[0];
-
-
-
- if (GlobalInformation.displayDependencies == true){
+
+ storiesFileName = args[0];
+
+ if (GlobalInformation.displayDependencies == true) {
/**
* handle dependencies
*/
-
+
Map<String, ArrayList<String>> dependencies = new TreeMap<String, ArrayList<String>>();
DefaultHandler depHandler = parseXMLDocumentDependencies(dependencies);
-
+
// start parsing
SAXParserFactory depFactoryMain = SAXParserFactory.newInstance();
depFactoryMain.setNamespaceAware(true);
try {
SAXParser saxParser = depFactoryMain.newSAXParser();
- InputStream in = new FileInputStream(depInFileName);
- if (depInFileName.endsWith(".gz")) {
+ InputStream in = new FileInputStream(depFileName);
+ if (depFileName.endsWith(".gz")) {
in = new GZIPInputStream(in);
}
in = new BufferedInputStream(in);
- saxParser.parse(in,depHandler);
+ saxParser.parse(in, depHandler);
} catch (ParserConfigurationException e) {
throw new RuntimeException("Could not parse document. ", e);
} catch (SAXException e) {
@@ -87,56 +93,93 @@
} catch (IOException e) {
throw new RuntimeException("Could not open file. ", e);
}
-
- try{
+
+ try {
MakeTopLevelHtmlForPerm.makeDependenciesHtml(dependencies);
} catch (IOException e) {
throw new RuntimeException("Cannot open file. ", e);
}
}
+
+ if (GlobalInformation.displaySplitPoints == true) {
+ /** handle runAsync split points
+ */
+
+ DefaultHandler splitPointHandler = parseXMLDocumentSplitPoints();
+
+ // start parsing
+ SAXParserFactory splitPointsFactoryMain = SAXParserFactory.newInstance();
+ splitPointsFactoryMain.setNamespaceAware(true);
+ try {
+ SAXParser saxParser = splitPointsFactoryMain.newSAXParser();
+ InputStream in = new FileInputStream(splitPointsFileName);
+ if (depFileName.endsWith(".gz")) {
+ in = new GZIPInputStream(in);
+ }
+ in = new BufferedInputStream(in);
+ saxParser.parse(in, splitPointHandler);
+ } catch (ParserConfigurationException e) {
+ throw new RuntimeException("Could not parse document. ", e);
+ } catch (SAXException e) {
+ throw new RuntimeException("Could not create SAX parser. ", e);
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException("Could not open file. ", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Could not open file. ", e);
+ }
+ }
+
/**
* handle everything else
*/
// to store literals data
- GlobalInformation.nameToLitColl.put("long",new LiteralsCollection("long"));
- GlobalInformation.nameToLitColl.put("null",new LiteralsCollection("null"));
- GlobalInformation.nameToLitColl.put("class",new LiteralsCollection("class"));
- GlobalInformation.nameToLitColl.put("int",new LiteralsCollection("int"));
- GlobalInformation.nameToLitColl.put("string",new LiteralsCollection("string"));
- GlobalInformation.nameToLitColl.put("number",new LiteralsCollection("number"));
- GlobalInformation.nameToLitColl.put("boolean",new LiteralsCollection("boolean"));
- GlobalInformation.nameToLitColl.put("double",new LiteralsCollection("double"));
- GlobalInformation.nameToLitColl.put("char",new LiteralsCollection("char"));
- GlobalInformation.nameToLitColl.put("undefined",new LiteralsCollection("undefined"));
- GlobalInformation.nameToLitColl.put("float",new LiteralsCollection("float"));
-
+ GlobalInformation.nameToLitColl.put("long", new LiteralsCollection("long"));
+ GlobalInformation.nameToLitColl.put("null", new LiteralsCollection("null"));
+ GlobalInformation.nameToLitColl.put("class",
+ new LiteralsCollection("class"));
+ GlobalInformation.nameToLitColl.put("int", new LiteralsCollection("int"));
+ GlobalInformation.nameToLitColl.put("string", new LiteralsCollection(
+ "string"));
+ GlobalInformation.nameToLitColl.put("number", new LiteralsCollection(
+ "number"));
+ GlobalInformation.nameToLitColl.put("boolean", new LiteralsCollection(
+ "boolean"));
+ GlobalInformation.nameToLitColl.put("double", new LiteralsCollection(
+ "double"));
+ GlobalInformation.nameToLitColl.put("char", new LiteralsCollection("char"));
+ GlobalInformation.nameToLitColl.put("undefined", new LiteralsCollection(
+ "undefined"));
+ GlobalInformation.nameToLitColl.put("float",
+ new LiteralsCollection("float"));
+
// to store code data
- GlobalInformation.nameToCodeColl.put("allOther", new CodeCollection("allOther"));
+ GlobalInformation.nameToCodeColl.put("allOther", new CodeCollection(
+ "allOther"));
GlobalInformation.nameToCodeColl.put("widget", new CodeCollection("widget"));
- GlobalInformation.nameToCodeColl.put("rpcUser", new CodeCollection("rpcUser"));
+ GlobalInformation.nameToCodeColl.put("rpcUser", new CodeCollection(
+ "rpcUser"));
GlobalInformation.nameToCodeColl.put("rpcGen", new CodeCollection("rpcGen"));
GlobalInformation.nameToCodeColl.put("rpcGwt", new CodeCollection("rpcGwt"));
GlobalInformation.nameToCodeColl.put("gwtLang", new CodeCollection("long"));
GlobalInformation.nameToCodeColl.put("jre", new CodeCollection("jre"));
-
-
- // make the parser handler
- DefaultHandler handler = parseXMLDocument(GlobalInformation.nameToLitColl, GlobalInformation.nameToCodeColl);
-
+ // make the parser handler
+ DefaultHandler handler = parseXMLDocument(GlobalInformation.nameToLitColl,
+ GlobalInformation.nameToCodeColl);
+
// start parsing
SAXParserFactory factoryMain = SAXParserFactory.newInstance();
factoryMain.setNamespaceAware(true);
try {
SAXParser saxParser = factoryMain.newSAXParser();
- InputStream in = new FileInputStream(inFileName);
- if (inFileName.endsWith(".gz")) {
+ InputStream in = new FileInputStream(storiesFileName);
+ if (storiesFileName.endsWith(".gz")) {
in = new GZIPInputStream(in);
}
in = new BufferedInputStream(in);
- saxParser.parse(in,handler);
+ saxParser.parse(in, handler);
} catch (ParserConfigurationException e) {
throw new RuntimeException("Could not parse document. ", e);
} catch (SAXException e) {
@@ -149,25 +192,25 @@
// add to "All Other Code" if none of the special categories apply
updateAllOtherCodeType(GlobalInformation.nameToCodeColl);
-
+
// now we need to aggregate numbers
GlobalInformation.computePackageSizes();
GlobalInformation.computePartialPackageSizes();
-
+
// clean up the RPC categories
foldInRPCHeuristic(GlobalInformation.nameToCodeColl);
-
+
// generate all the html files
- makeHTMLFiles(GlobalInformation.nameToLitColl, GlobalInformation.nameToCodeColl);
-
+ makeHTMLFiles(GlobalInformation.nameToLitColl,
+ GlobalInformation.nameToCodeColl);
+
System.out.println("Finished creating reports. To see the dashboard, open SoycDashboard-index.html in your browser.");
}
-
private static DefaultHandler parseXMLDocument(
final TreeMap<String, LiteralsCollection> nameToLitColl,
final HashMap<String, CodeCollection> nameToCodeColl) {
-
+
DefaultHandler handler = new DefaultHandler() {
String curStoryId;
@@ -178,302 +221,297 @@
HashSet<String> curRelevantLitTypes = new HashSet<String>();
HashSet<String> curRelevantCodeTypes = new HashSet<String>();
String curClassId;
- String curPackage;
Integer curFragment;
- String curFunctionId = "";
boolean specialCodeType = false;
StringBuilder valueBuilder = new StringBuilder();
int ct = 0;
boolean fragmentInLoadOrder = false;
-
+
/**
- * This method deals with the beginning of the XML element.
- * It analyzes the XML node and adds its information to the relevant literal or code collection for later analysis.
- * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+ * This method deals with the beginning of the XML element. It analyzes
+ * the XML node and adds its information to the relevant literal or code
+ * collection for later analysis.
+ *
+ * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
+ * java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
@Override
- public void startElement(String nsUri, String strippedName, String tagName, Attributes attributes) {
-
- if ((ct % 10000) == 0){
+ public void startElement(String nsUri, String strippedName,
+ String tagName, Attributes attributes) {
+
+ if ((ct % 10000) == 0) {
System.out.println(ct);
}
ct++;
-
- valueBuilder.delete(0,valueBuilder.length());
-
- if (strippedName.compareTo("splitpoint") == 0){
- System.out.println("about to process splitpoint");
- parseSplitPoint(attributes);
- }
- else if ((strippedName.compareTo("package") == 0)&&(attributes.getValue("id") != null)){
- curPackage = attributes.getValue("id");
-
- if (curPackage.compareTo("") == 0){
- curPackage = "emptyPackageName";
- }
-
- if (! GlobalInformation.packageToClasses.containsKey(curPackage)){
- TreeSet<String> insertSet = new TreeSet<String>();
- GlobalInformation.packageToClasses.put(curPackage, insertSet);
- }
- }
-
- else if (strippedName.compareTo("class") == 0){
-
- parseClass(nameToCodeColl, attributes);
- }
- else if (strippedName.compareTo("function") == 0){
- if (attributes.getValue("id") != null){
- curFunctionId = attributes.getValue("id");
- }
- }
-
- //TODO(kprobst): not currently used, but will be for dependencies
- else if (strippedName.compareTo("on") == 0){
- parseDependsOn(nameToCodeColl, attributes);
- }
-
- else if (strippedName.compareTo("of") == 0){
- parseOverrides(nameToCodeColl, attributes);
- }
+ valueBuilder.delete(0, valueBuilder.length());
- else if (strippedName.compareTo("by") == 0){
- parseCorrelations(nameToCodeColl, attributes);
- }
-
- else if (strippedName.compareTo("story") == 0){
+ if (strippedName.compareTo("story") == 0) {
parseStory(attributes);
}
- else if (strippedName.compareTo("origin") == 0){
+ else if (strippedName.compareTo("of") == 0) {
+ parseOverrides(nameToCodeColl, attributes);
+ }
+
+ else if (strippedName.compareTo("by") == 0) {
+ parseCorrelations(nameToCodeColl, attributes);
+ }
+
+ else if (strippedName.compareTo("origin") == 0) {
parseOrigins(nameToLitColl, attributes);
}
-
- else if (strippedName.compareTo("js") == 0){
- if (attributes.getValue("fragment") != null){
+
+ else if (strippedName.compareTo("js") == 0) {
+ if (attributes.getValue("fragment") != null) {
// ignore all code that is not in the first load order
-
+
curFragment = Integer.parseInt(attributes.getValue("fragment"));
- if((curFragment == 0)||
- (curFragment == (GlobalInformation.numSplitPoints+1))||
- (curFragment == (GlobalInformation.numSplitPoints+2))||
- ((curFragment >= 2) && (curFragment <= GlobalInformation.numSplitPoints))){
+ if ((curFragment == 0)
+ || (curFragment == (GlobalInformation.numSplitPoints + 1))
+ || (curFragment == (GlobalInformation.numSplitPoints + 2))
+ || ((curFragment >= 2) && (curFragment <= GlobalInformation.numSplitPoints))) {
fragmentInLoadOrder = true;
- }
- else{
+ } else {
fragmentInLoadOrder = false;
}
- }
- else{
-
+ } else {
+
curFragment = -2;
}
}
- else if (strippedName.compareTo("storyref") == 0){
+ else if (strippedName.compareTo("storyref") == 0) {
parseJs(nameToLitColl, nameToCodeColl, attributes, curFragment);
}
}
-
/**
- * This method collects a block of the value of the current XML node that the SAX parser parses.
- * It simply adds to the the previous blocks, so that we can collect the entire value block.
+ * This method collects a block of the value of the current XML node that
+ * the SAX parser parses. It simply adds to the the previous blocks, so
+ * that we can collect the entire value block.
*/
- @Override
- public void characters (char ch[], int start, int length){
- valueBuilder.append(ch, start, length);
- }
-
-
- /**
- * This method marks the end of an XML element that the SAX parser parses.
- * It has access to the full value of the node and uses it add information to the relevant literal or code collections.
- * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
- */
@Override
- public void endElement (String nsUri, String strippedName, String qName){
- String value = valueBuilder.toString();
+ public void characters(char ch[], int start, int length) {
+ valueBuilder.append(ch, start, length);
+ }
+
+ /**
+ * This method marks the end of an XML element that the SAX parser parses.
+ * It has access to the full value of the node and uses it to add information
+ * to the relevant literal or code collections.
+ *
+ * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
+ * java.lang.String, java.lang.String)
+ */
+ @Override
+ public void endElement(String nsUri, String strippedName, String qName) {
- int numBytes = value.getBytes().length;
-
- if (curStoryRef != null){
-
- //add this size to the current fragment
- if (GlobalInformation.storiesToCorrClasses.containsKey(curStoryRef)){
-
- if ((GlobalInformation.storiesToLitType.containsKey(curStoryRef))&&(GlobalInformation.storiesToCorrClasses.get(curStoryRef).size() > 0)){
- GlobalInformation.numBytesDoubleCounted += numBytes;
- }
-
- float partialSize = (float)numBytes / (float)GlobalInformation.storiesToCorrClasses.get(curStoryRef).size();
- if (!GlobalInformation.fragmentToPartialSize.containsKey(curFragment)){
- GlobalInformation.fragmentToPartialSize.put(curFragment, partialSize);
- }
- else{
- float newSize = GlobalInformation.fragmentToPartialSize.get(curFragment) + partialSize;
+ if (strippedName.compareTo("storyref") == 0){
+ String value = valueBuilder.toString();
+
+ int numBytes = value.getBytes().length;
+ if (curStoryRef != null) {
+ if (!GlobalInformation.fragmentToPartialSize.containsKey(curFragment)) {
+ GlobalInformation.fragmentToPartialSize.put(curFragment,
+ (float)numBytes);
+ } else {
+ float newSize = GlobalInformation.fragmentToPartialSize.get(curFragment)
+ + (float)numBytes;
GlobalInformation.fragmentToPartialSize.put(curFragment, newSize);
}
-
- // now do different things depending on whether this fragment is in the load order or not
- if (fragmentInLoadOrder == false){
+
+ // now do different things depending on whether this fragment is in
+ // the load order or not
+ if (fragmentInLoadOrder == false) {
GlobalInformation.allOtherFragmentsPartialSize += numBytes;
- }
- else{
+ } else {
GlobalInformation.cumSizeAllCode += numBytes;
-
- if ((!GlobalInformation.storiesToLitType.containsKey(curStoryRef))&&
- (!GlobalInformation.storiesToCorrClasses.containsKey(curStoryRef))){
- GlobalInformation.nonAttributedStories.add(curStoryRef);
- GlobalInformation.nonAttributedBytes += numBytes;
+ }
+
+
+ // add this size to the classes associated with it
+ if (GlobalInformation.storiesToCorrClasses.containsKey(curStoryRef)) {
+
+ if ((GlobalInformation.storiesToLitType.containsKey(curStoryRef))
+ && (GlobalInformation.storiesToCorrClasses.get(curStoryRef).size() > 0)) {
+ GlobalInformation.numBytesDoubleCounted += numBytes;
}
-
-
- // go through all the classes for this story
- for (String className : GlobalInformation.storiesToCorrClasses.get(curStoryRef)){
- // get the corresponding package
- if (GlobalInformation.classToPackage.containsKey(className)){
- String packageName = GlobalInformation.classToPackage.get(className);
+
+ float partialSize = (float) numBytes
+ / (float) GlobalInformation.storiesToCorrClasses.get(
+ curStoryRef).size();
+
+ // now do different things depending on whether this fragment is in
+ // the load order or not
+ if (fragmentInLoadOrder == true) {
+ if ((!GlobalInformation.storiesToLitType.containsKey(curStoryRef))
+ && (!GlobalInformation.storiesToCorrClasses.containsKey(curStoryRef))) {
+ GlobalInformation.nonAttributedStories.add(curStoryRef);
+ GlobalInformation.nonAttributedBytes += numBytes;
+ }
+
+ // go through all the classes for this story
+ for (String className : GlobalInformation.storiesToCorrClasses.get(curStoryRef)) {
+ // get the corresponding package
- if (!GlobalInformation.packageToClasses.containsKey(packageName)){
+ String packageName = "";
+
+
+ if (!GlobalInformation.classToPackage.containsKey(className)) {
+ //derive the package name from the class
+ packageName = className;
+ packageName = packageName.replaceAll("\\.[A-Z].*","");
+ GlobalInformation.classToPackage.put(className, packageName);
+ }
+ else{
+ packageName = GlobalInformation.classToPackage.get(className);
+ }
+ parseClass(nameToCodeColl, className, packageName);
+
+ if (!GlobalInformation.packageToClasses.containsKey(packageName)) {
TreeSet<String> insertSet = new TreeSet<String>();
insertSet.add(className);
- GlobalInformation.packageToClasses.put(packageName, insertSet);
+ GlobalInformation.packageToClasses.put(packageName,
+ insertSet);
+ } else {
+ GlobalInformation.packageToClasses.get(packageName).add(
+ className);
}
- else{
- GlobalInformation.packageToClasses.get(packageName).add(className);
- }
-
- if (GlobalInformation.classToSize.containsKey(className)){
- int newSize = GlobalInformation.classToSize.get(className) + numBytes;
+
+ if (GlobalInformation.classToSize.containsKey(className)) {
+ int newSize = GlobalInformation.classToSize.get(className)
+ + numBytes;
GlobalInformation.classToSize.put(className, newSize);
+ } else {
+ GlobalInformation.classToSize.put(className, numBytes);
}
- else{
- GlobalInformation.classToSize.put(className, numBytes);
- }
-
- if (GlobalInformation.classToPartialSize.containsKey(className)){
- float newSize = GlobalInformation.classToPartialSize.get(className) + partialSize;
+
+ if (GlobalInformation.classToPartialSize.containsKey(className)) {
+ float newSize = GlobalInformation.classToPartialSize.get(className)
+ + partialSize;
GlobalInformation.classToPartialSize.put(className, newSize);
- }
- else{
- GlobalInformation.classToPartialSize.put(className, partialSize);
+ } else {
+ GlobalInformation.classToPartialSize.put(className,
+ partialSize);
}
}
}
}
+ updateLitTypes(nameToLitColl, value, numBytes);
}
- updateLitTypes(nameToLitColl, value, numBytes);
}
}
-
/*
* This method assigns strings to the appropriate category
*/
private void updateLitTypes(
final TreeMap<String, LiteralsCollection> nameToLitColl,
String value, int numBytes) {
-
+
int iNumCounted = 0;
-
- for (String relLitType : curRelevantLitTypes){
+
+ for (String relLitType : curRelevantLitTypes) {
iNumCounted++;
-
- //then give string literals special treatment
- if (relLitType.compareTo("string") == 0){
-
- // note that this will double-count (i.e., it will count a string twice if it's in the output twice), as it should.
+
+ // then give string literals special treatment
+ if (relLitType.compareTo("string") == 0) {
+
+ // note that this will double-count (i.e., it will count a string
+ // twice if it's in the output twice), as it should.
nameToLitColl.get("string").cumStringSize += numBytes;
nameToLitColl.get(relLitType).cumSize += numBytes;
-
- //get the origins
+
+ // get the origins
HashSet<String> originSet = nameToLitColl.get("string").storyToLocations.get(curStoryRef);
-
+
// find the most appropriate string literal category
String mostAppropriateCategory = "";
String mostAppropriateLocation = "";
String backupLocation = "";
- for (String origin : originSet){
-
- if ((origin.contains("ClassLiteralHolder")) && (mostAppropriateCategory.compareTo("") == 0)){
+ for (String origin : originSet) {
+
+ if ((origin.contains("ClassLiteralHolder"))
+ && (mostAppropriateCategory.compareTo("") == 0)) {
mostAppropriateCategory = "compiler";
mostAppropriateLocation = origin;
- }
- else if ((origin.startsWith("transient source for"))&&(origin.contains("_TypeSerializer")) && (mostAppropriateCategory.compareTo("") == 0)){
+ } else if ((origin.startsWith("transient source for"))
+ && (origin.contains("_TypeSerializer"))
+ && (mostAppropriateCategory.compareTo("") == 0)) {
mostAppropriateCategory = "transient";
mostAppropriateLocation = origin;
- }
- else if ((origin.contains("InlineResourceBundleGenerator")) && (mostAppropriateCategory.compareTo("") == 0)){
+ } else if ((origin.contains("InlineResourceBundleGenerator"))
+ && (mostAppropriateCategory.compareTo("") == 0)) {
mostAppropriateCategory = "inlinedTextRes";
mostAppropriateLocation = origin;
}
- if (origin.compareTo("com.google.gwt.dev.js.ast.JsProgram: Line 0") != 0){
+ if (origin.compareTo("com.google.gwt.dev.js.ast.JsProgram: Line 0") != 0) {
backupLocation = origin;
}
}
- if (backupLocation.compareTo("") == 0){
+ if (backupLocation.compareTo("") == 0) {
backupLocation = "com.google.gwt.dev.js.ast.JsProgram: Line 0";
}
- if ((((value.startsWith("'")) && (value.endsWith("'"))) ||
- ((value.startsWith("\""))&&(value.endsWith("\"")))) &&
- (mostAppropriateCategory.compareTo("") == 0)){
+ if ((((value.startsWith("'")) && (value.endsWith("'"))) || ((value.startsWith("\"")) && (value.endsWith("\""))))
+ && (mostAppropriateCategory.compareTo("") == 0)) {
mostAppropriateCategory = "user";
mostAppropriateLocation = backupLocation;
- }
- else if (mostAppropriateCategory.compareTo("") == 0){
+ } else if (mostAppropriateCategory.compareTo("") == 0) {
mostAppropriateCategory = "otherStrings";
mostAppropriateLocation = backupLocation;
}
-
- if (!nameToLitColl.get("string").stringLiteralToType.containsKey(value)){
- nameToLitColl.get("string").stringLiteralToType.put(value, mostAppropriateCategory);
- if (!nameToLitColl.get("string").stringTypeToCount.containsKey(mostAppropriateCategory)){
- nameToLitColl.get("string").stringTypeToCount.put(mostAppropriateCategory, 1);
- }
- else{
- int iNewCount = nameToLitColl.get("string").stringTypeToCount.get(mostAppropriateCategory) + 1;
- nameToLitColl.get("string").stringTypeToCount.put(mostAppropriateCategory, iNewCount);
+
+ if (!nameToLitColl.get("string").stringLiteralToType.containsKey(value)) {
+ nameToLitColl.get("string").stringLiteralToType.put(value,
+ mostAppropriateCategory);
+ if (!nameToLitColl.get("string").stringTypeToCount.containsKey(mostAppropriateCategory)) {
+ nameToLitColl.get("string").stringTypeToCount.put(
+ mostAppropriateCategory, 1);
+ } else {
+ int iNewCount = nameToLitColl.get("string").stringTypeToCount.get(mostAppropriateCategory) + 1;
+ nameToLitColl.get("string").stringTypeToCount.put(
+ mostAppropriateCategory, iNewCount);
}
-
int iNewSize = numBytes;
- if (nameToLitColl.get("string").stringTypeToSize.containsKey(mostAppropriateCategory)){
+ if (nameToLitColl.get("string").stringTypeToSize.containsKey(mostAppropriateCategory)) {
iNewSize += nameToLitColl.get("string").stringTypeToSize.get(mostAppropriateCategory);
}
- nameToLitColl.get("string").stringTypeToSize.put(mostAppropriateCategory, iNewSize);
+ nameToLitColl.get("string").stringTypeToSize.put(
+ mostAppropriateCategory, iNewSize);
-
- if (nameToLitColl.get("string").storyToLocations.containsKey(curStoryRef)){
+ if (nameToLitColl.get("string").storyToLocations.containsKey(curStoryRef)) {
HashSet<String> insertSet = new HashSet<String>();
insertSet.add(mostAppropriateLocation);
- nameToLitColl.get(relLitType).literalToLocations.put(value,insertSet);
+ nameToLitColl.get(relLitType).literalToLocations.put(value,
+ insertSet);
}
- }
+ }
}
- else{
- // note that this will double-count (i.e., it will count a literal twice if it's in the output twice), as it should.
+ else {
+ // note that this will double-count (i.e., it will count a literal
+ // twice if it's in the output twice), as it should.
nameToLitColl.get(relLitType).cumSize += numBytes;
-
- if (nameToLitColl.get(relLitType).storyToLocations.containsKey(curStoryRef)){
- if (nameToLitColl.get(relLitType).literalToLocations.containsKey(value)){
- nameToLitColl.get(relLitType).literalToLocations.get(value).addAll(nameToLitColl.get(relLitType).
- storyToLocations.get(curStoryRef));
- }
- else{
+
+ if (nameToLitColl.get(relLitType).storyToLocations.containsKey(curStoryRef)) {
+ if (nameToLitColl.get(relLitType).literalToLocations.containsKey(value)) {
+ nameToLitColl.get(relLitType).literalToLocations.get(value).addAll(
+ nameToLitColl.get(relLitType).storyToLocations.get(curStoryRef));
+ } else {
HashSet<String> insertSet = nameToLitColl.get(relLitType).storyToLocations.get(curStoryRef);
- nameToLitColl.get(relLitType).literalToLocations.put(value,insertSet);
+ nameToLitColl.get(relLitType).literalToLocations.put(value,
+ insertSet);
}
-
+
}
- }
+ }
}
}
-
- /*
+
+ /*
* parses the "JS" portion of the XML file
*/
private void parseJs(
@@ -482,39 +520,39 @@
Attributes attributes, Integer curFragment) {
curRelevantLitTypes.clear();
curRelevantCodeTypes.clear();
-
- if (attributes.getValue("idref") != null){
-
+
+ if (attributes.getValue("idref") != null) {
+
curStoryRef = attributes.getValue("idref");
-
- if (curFragment != -1){
- //add this to the stories for this fragment
- if (!GlobalInformation.fragmentToStories.containsKey(curFragment)){
+
+ if (curFragment != -1) {
+ // add this to the stories for this fragment
+ if (!GlobalInformation.fragmentToStories.containsKey(curFragment)) {
HashSet<String> insertSet = new HashSet<String>();
insertSet.add(curStoryRef);
GlobalInformation.fragmentToStories.put(curFragment, insertSet);
- }
- else{
- GlobalInformation.fragmentToStories.get(curFragment).add(curStoryRef);
+ } else {
+ GlobalInformation.fragmentToStories.get(curFragment).add(
+ curStoryRef);
}
}
-
- for (String litType : nameToLitColl.keySet()){
- if (nameToLitColl.get(litType).storyToLocations.containsKey(curStoryRef)){
+
+ for (String litType : nameToLitColl.keySet()) {
+ if (nameToLitColl.get(litType).storyToLocations.containsKey(curStoryRef)) {
curRelevantLitTypes.add(litType);
}
}
-
+
specialCodeType = false;
- for (String codeType : nameToCodeColl.keySet()){
- if (nameToCodeColl.get(codeType).stories.contains(curStoryRef)){
+ for (String codeType : nameToCodeColl.keySet()) {
+ if (nameToCodeColl.get(codeType).stories.contains(curStoryRef)) {
curRelevantCodeTypes.add(codeType);
specialCodeType = true;
}
}
- if (specialCodeType == false){
-
- nameToCodeColl.get("allOther").stories.add(curStoryRef);
+ if (specialCodeType == false) {
+
+ nameToCodeColl.get("allOther").stories.add(curStoryRef);
curRelevantCodeTypes.add("allOther");
}
}
@@ -526,66 +564,43 @@
private void parseOrigins(
final TreeMap<String, LiteralsCollection> nameToLitColl,
Attributes attributes) {
- if ((curStoryLiteralType.compareTo("") != 0)&&
- (attributes.getValue("lineNumber") != null)&&
- (attributes.getValue("location") != null)){
+ if ((curStoryLiteralType.compareTo("") != 0)
+ && (attributes.getValue("lineNumber") != null)
+ && (attributes.getValue("location") != null)) {
curLineNumber = attributes.getValue("lineNumber");
curLocation = attributes.getValue("location");
String curOrigin = curLocation + ": Line " + curLineNumber;
-
- if (!nameToLitColl.get(curStoryLiteralType).storyToLocations.containsKey(curStoryId)){
+
+ if (!nameToLitColl.get(curStoryLiteralType).storyToLocations.containsKey(curStoryId)) {
HashSet<String> insertSet = new HashSet<String>();
insertSet.add(curOrigin);
- nameToLitColl.get(curStoryLiteralType).storyToLocations.put(curStoryId, insertSet);
- }
- else{
- nameToLitColl.get(curStoryLiteralType).storyToLocations.get(curStoryId).add(curOrigin);
+ nameToLitColl.get(curStoryLiteralType).storyToLocations.put(
+ curStoryId, insertSet);
+ } else {
+ nameToLitColl.get(curStoryLiteralType).storyToLocations.get(
+ curStoryId).add(curOrigin);
}
}
}
/*
- * parses the split points
- */
- private void parseSplitPoint(Attributes attributes){
- System.out.println("processing split point");
- if (attributes.getValue("id") != null){
- String curSplitPoint = attributes.getValue("id");
- System.out.println("\tcurSplitPoint is: " + curSplitPoint);
- if (attributes.getValue("location") != null){
- String curSplitPointLocation = attributes.getValue("location");
-
- curSplitPointLocation = curSplitPointLocation.replaceAll("\\(L.*","");
-
- System.out.println("\tcurSplitPointLocation is: " + curSplitPointLocation);
- GlobalInformation.splitPointToLocation.put(Integer.parseInt(curSplitPoint), curSplitPointLocation);
- GlobalInformation.numSplitPoints++;
-
- System.out.println("adding split point and location: " + curSplitPoint + "-->" + curSplitPointLocation);
- System.out.println("\t(Number of split points is now: " + GlobalInformation.numSplitPoints + ")");
-
- }
- }
- }
-
- /*
* parses the "story" portion of the XML file
*/
private void parseStory(Attributes attributes) {
- if (attributes.getValue("id") != null){
+ if (attributes.getValue("id") != null) {
curStoryId = attributes.getValue("id");
- if (attributes.getValue("literal") != null){
+ if (attributes.getValue("literal") != null) {
curStoryLiteralType = attributes.getValue("literal");
- GlobalInformation.storiesToLitType.put(curStoryId, curStoryLiteralType);
-
+ GlobalInformation.storiesToLitType.put(curStoryId,
+ curStoryLiteralType);
- if (!nameToLitColl.get(curStoryLiteralType).storyToLocations.containsKey(curStoryId)){
+ if (!nameToLitColl.get(curStoryLiteralType).storyToLocations.containsKey(curStoryId)) {
HashSet<String> insertSet = new HashSet<String>();
- nameToLitColl.get(curStoryLiteralType).storyToLocations.put(curStoryId, insertSet);
+ nameToLitColl.get(curStoryLiteralType).storyToLocations.put(
+ curStoryId, insertSet);
}
-
- }
- else{
+
+ } else {
curStoryLiteralType = "";
}
}
@@ -598,41 +613,37 @@
final HashMap<String, CodeCollection> nameToCodeColl,
Attributes attributes) {
- if (attributes.getValue("idref") != null){
-
+ if (attributes.getValue("idref") != null) {
+
String corrClassOrMethod = attributes.getValue("idref");
-
String corrClass = attributes.getValue("idref");
-
- if (corrClass.contains(":")){
+
+ if (corrClass.contains(":")) {
corrClass = corrClass.replaceAll(":.*", "");
}
-
- if (GlobalInformation.classToPackage.containsKey(corrClass)){ //if we know about this class
-
- if (! GlobalInformation.storiesToCorrClassesAndMethods.containsKey(curStoryId)){
- HashSet<String> insertSet = new HashSet<String>();
- insertSet.add(corrClassOrMethod);
- GlobalInformation.storiesToCorrClassesAndMethods.put(curStoryId, insertSet);
- }
- else{
- GlobalInformation.storiesToCorrClassesAndMethods.get(curStoryId).add(corrClassOrMethod);
- }
-
-
- if (! GlobalInformation.storiesToCorrClasses.containsKey(curStoryId)){
- HashSet<String> insertSet = new HashSet<String>();
- insertSet.add(corrClass);
- GlobalInformation.storiesToCorrClasses.put(curStoryId, insertSet);
- }
- else{
- GlobalInformation.storiesToCorrClasses.get(curStoryId).add(corrClass);
- }
-
- for (String codeType : nameToCodeColl.keySet()){
- if (nameToCodeColl.get(codeType).classes.contains(corrClass)){
- nameToCodeColl.get(codeType).stories.add(curStoryId);
- }
+
+ if (!GlobalInformation.storiesToCorrClassesAndMethods.containsKey(curStoryId)) {
+ HashSet<String> insertSet = new HashSet<String>();
+ insertSet.add(corrClassOrMethod);
+ GlobalInformation.storiesToCorrClassesAndMethods.put(curStoryId,
+ insertSet);
+ } else {
+ GlobalInformation.storiesToCorrClassesAndMethods.get(curStoryId).add(
+ corrClassOrMethod);
+ }
+
+ if (!GlobalInformation.storiesToCorrClasses.containsKey(curStoryId)) {
+ HashSet<String> insertSet = new HashSet<String>();
+ insertSet.add(corrClass);
+ GlobalInformation.storiesToCorrClasses.put(curStoryId, insertSet);
+ } else {
+ GlobalInformation.storiesToCorrClasses.get(curStoryId).add(
+ corrClass);
+ }
+
+ for (String codeType : nameToCodeColl.keySet()) {
+ if (nameToCodeColl.get(codeType).classes.contains(corrClass)) {
+ nameToCodeColl.get(codeType).stories.add(curStoryId);
}
}
}
@@ -644,23 +655,21 @@
private void parseOverrides(
final HashMap<String, CodeCollection> nameToCodeColl,
Attributes attributes) {
- if (attributes.getValue("idref") != null){
+ if (attributes.getValue("idref") != null) {
String overriddenClass = attributes.getValue("idref");
-
- //TODO(kprobst): fix this -- we either generalize to classes, or the numbers are messed up...
- if (overriddenClass.contains(":")){
+ // we either generalize to classes, or the
+ // numbers are messed up...
+ if (overriddenClass.contains(":")) {
overriddenClass = overriddenClass.replaceAll(":.*", "");
}
-
- if (overriddenClass.compareTo("com.google.gwt.user.client.ui.UIObject") == 0){
+
+ if (overriddenClass.compareTo("com.google.gwt.user.client.ui.UIObject") == 0) {
nameToCodeColl.get("widget").classes.add(curClassId);
- }
- else if (overriddenClass.contains("java.io.Serializable") ||
- overriddenClass.contains("IsSerializable")){
+ } else if (overriddenClass.contains("java.io.Serializable")
+ || overriddenClass.contains("IsSerializable")) {
nameToCodeColl.get("rpcUser").classes.add(curClassId);
- }
- else if (overriddenClass.contains("com.google.gwt.user.client.rpc.core.java")){
+ } else if (overriddenClass.contains("com.google.gwt.user.client.rpc.core.java")) {
nameToCodeColl.get("rpcGwt").classes.add(curClassId);
}
}
@@ -669,97 +678,96 @@
/*
* parses the "class" portion of the XML file
*/
- private void parseClass(
- final HashMap<String, CodeCollection> nameToCodeColl,
- Attributes attributes) {
- if (attributes.getValue("id") != null){
- curClassId = attributes.getValue("id");
+ private void parseClass(final HashMap<String, CodeCollection> nameToCodeColl,
+ String curClassId, String curPackage) {
+ //if (attributes.getValue("id") != null) {
+ // curClassId = attributes.getValue("id");
- GlobalInformation.classToPackage.put(curClassId, curPackage);
+ // GlobalInformation.classToPackage.put(curClassId, curPackage);
- if (curPackage.startsWith("java")){
+ if (curPackage.startsWith("java")) {
nameToCodeColl.get("jre").classes.add(curClassId);
- }
- else if (curPackage.startsWith("com.google.gwt.lang")){
+ } else if (curPackage.startsWith("com.google.gwt.lang")) {
nameToCodeColl.get("gwtLang").classes.add(curClassId);
}
- if (curClassId.contains("_CustomFieldSerializer")){
+ if (curClassId.contains("_CustomFieldSerializer")) {
nameToCodeColl.get("rpcUser").classes.add(curClassId);
- }
- else if (curClassId.endsWith("_FieldSerializer") ||
- curClassId.endsWith("_Proxy") ||
- curClassId.endsWith("_TypeSerializer")){
+ } else if (curClassId.endsWith("_FieldSerializer")
+ || curClassId.endsWith("_Proxy")
+ || curClassId.endsWith("_TypeSerializer")) {
nameToCodeColl.get("rpcGen").classes.add(curClassId);
}
- }
+ //}
}
-
+
/*
* parses the "depends on" portion of the XML file
*/
- private void parseDependsOn(final HashMap<String, CodeCollection> nameToCodeColl, Attributes attributes) {
- if (curFunctionId.compareTo("") == 0){
- if (attributes.getValue("idref") != null){
+/* private void parseDependsOn(
+ final HashMap<String, CodeCollection> nameToCodeColl,
+ Attributes attributes) {
+ if (curFunctionId.compareTo("") == 0) {
+ if (attributes.getValue("idref") != null) {
String curDepClassId = attributes.getValue("idref");
-
- if (curDepClassId.contains(":")){
- // strip everything after the :: (to get to class, even if it's a method)
+
+ if (curDepClassId.contains(":")) {
+ // strip everything after the :: (to get to class, even if it's a
+ // method)
curDepClassId = curDepClassId.replaceAll(":.*", "");
}
-
- if (curDepClassId.contains(".")){
- if (! GlobalInformation.classToWhatItDependsOn.containsKey(curClassId)){
+
+ if (curDepClassId.contains(".")) {
+ if (!GlobalInformation.classToWhatItDependsOn.containsKey(curClassId)) {
HashSet<String> insertSet = new HashSet<String>();
insertSet.add(curDepClassId);
- GlobalInformation.classToWhatItDependsOn.put(curClassId, insertSet);
- }
- else{
- GlobalInformation.classToWhatItDependsOn.get(curClassId).add(curDepClassId);
+ GlobalInformation.classToWhatItDependsOn.put(curClassId,
+ insertSet);
+ } else {
+ GlobalInformation.classToWhatItDependsOn.get(curClassId).add(
+ curDepClassId);
}
}
}
}
- }
+ }*/
};
return handler;
}
-
-
-
-
+ private static DefaultHandler parseXMLDocumentDependencies(
+ final Map<String, ArrayList<String>> dependencies) {
-
- private static DefaultHandler parseXMLDocumentDependencies(final Map<String, ArrayList<String>> dependencies) {
-
DefaultHandler handler = new DefaultHandler() {
StringBuilder valueBuilder = new StringBuilder();
// may want to create a class for this later
String curMethod;
-
+
/**
- * This method deals with the beginning of the XML element.
- * It analyzes the XML node and adds its information to the relevant literal or code collection for later analysis.
- * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+ * This method deals with the beginning of the XML element. It analyzes
+ * the XML node and adds its information to the relevant literal or code
+ * collection for later analysis.
+ *
+ * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
+ * java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
@Override
- public void startElement(String nsUri, String strippedName, String tagName, Attributes attributes) {
-
- valueBuilder.delete(0,valueBuilder.length());
-
-
- if ((strippedName.compareTo("method") == 0)&&(attributes.getValue("name") != null)){
+ public void startElement(String nsUri, String strippedName,
+ String tagName, Attributes attributes) {
+
+ valueBuilder.delete(0, valueBuilder.length());
+
+ if ((strippedName.compareTo("method") == 0)
+ && (attributes.getValue("name") != null)) {
curMethod = attributes.getValue("name");
- }
- else if ((strippedName.compareTo("called") == 0)&&(attributes.getValue("by") != null)){
+ } else if ((strippedName.compareTo("called") == 0)
+ && (attributes.getValue("by") != null)) {
String curDepMethod = attributes.getValue("by");
- if (!dependencies.containsKey(curMethod)){
+ if (!dependencies.containsKey(curMethod)) {
ArrayList<String> insertArray = new ArrayList<String>();
insertArray.add(curDepMethod);
dependencies.put(curMethod, insertArray);
- }
- else{
+ } else {
dependencies.get(curMethod).add(curDepMethod);
}
}
@@ -768,10 +776,56 @@
};
return handler;
}
-
-
-
+ private static DefaultHandler parseXMLDocumentSplitPoints() {
+
+ DefaultHandler handler = new DefaultHandler() {
+
+ /**
+ * This method deals with the beginning of the XML element. It analyzes
+ * the XML node and adds its information to the relevant literal or code
+ * collection for later analysis.
+ *
+ * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
+ * java.lang.String, java.lang.String, org.xml.sax.Attributes)
+ */
+ @Override
+ public void startElement(String nsUri, String strippedName,
+ String tagName, Attributes attributes) {
+ if (strippedName.compareTo("splitpoint") == 0) {
+ parseSplitPoint(attributes);
+ }
+ }
+
+ /*
+ * parses the split points
+ */
+ private void parseSplitPoint(Attributes attributes) {
+ if (attributes.getValue("id") != null) {
+ String curSplitPoint = attributes.getValue("id");
+ if (attributes.getValue("location") != null) {
+ String curSplitPointLocation = attributes.getValue("location");
+
+ curSplitPointLocation = curSplitPointLocation.replaceAll("\\(L.*",
+ "");
+
+ GlobalInformation.splitPointToLocation.put(
+ Integer.parseInt(curSplitPoint), curSplitPointLocation);
+ GlobalInformation.numSplitPoints++;
+
+ System.out.println("adding split point and location: "
+ + curSplitPoint + "-->" + curSplitPointLocation);
+ }
+ }
+ }
+
+
+
+ };
+ return handler;
+ }
+
+
/*
* cleans up the RPC code categories
@@ -779,37 +833,35 @@
private static void foldInRPCHeuristic(
final HashMap<String, CodeCollection> nameToCodeColl) {
/**
- * Heuristic: this moves all classes that override serializable from RPC to "Other Code" *if* there is no RPC generated code, i.e., if the
+ * Heuristic: this moves all classes that override serializable from RPC to
+ * "Other Code" *if* there is no RPC generated code, i.e., if the
* application really is not using RPC
*/
-
-
- if (nameToCodeColl.get("rpcGen").classes.size() == 0){
-
- for (String className : nameToCodeColl.get("rpcUser").classes){
-
- if ((! nameToCodeColl.get("widget").classes.contains(className))&&
- (! nameToCodeColl.get("jre").classes.contains(className))&&
- (! nameToCodeColl.get("gwtLang").classes.contains(className))){
- nameToCodeColl.get("allOther").classes.add(className);
- }
+
+ if (nameToCodeColl.get("rpcGen").classes.size() == 0) {
+
+ for (String className : nameToCodeColl.get("rpcUser").classes) {
+
+ if ((!nameToCodeColl.get("widget").classes.contains(className))
+ && (!nameToCodeColl.get("jre").classes.contains(className))
+ && (!nameToCodeColl.get("gwtLang").classes.contains(className))) {
+ nameToCodeColl.get("allOther").classes.add(className);
+ }
}
nameToCodeColl.get("rpcUser").classes.clear();
-
- for (String className : nameToCodeColl.get("rpcGwt").classes){
- if ((! nameToCodeColl.get("widget").classes.contains(className))&&
- (! nameToCodeColl.get("jre").classes.contains(className))&&
- (! nameToCodeColl.get("gwtLang").classes.contains(className))){
- nameToCodeColl.get("allOther").classes.add(className);
- }
-
+
+ for (String className : nameToCodeColl.get("rpcGwt").classes) {
+ if ((!nameToCodeColl.get("widget").classes.contains(className))
+ && (!nameToCodeColl.get("jre").classes.contains(className))
+ && (!nameToCodeColl.get("gwtLang").classes.contains(className))) {
+ nameToCodeColl.get("allOther").classes.add(className);
+ }
+
}
nameToCodeColl.get("rpcGwt").classes.clear();
}
-
-
- }
+ }
/*
* generates all the HTML files
@@ -823,57 +875,46 @@
MakeTopLevelHtmlForPerm.makeCodeTypeClassesHtmls(nameToCodeColl);
MakeTopLevelHtmlForPerm.makeLiteralsClassesTableHtmls(nameToLitColl);
MakeTopLevelHtmlForPerm.makeStringLiteralsClassesTableHtmls(nameToLitColl);
- // MakeTopLevelHtmlForPerm.makeFragmentClassesHtmls();
MakeTopLevelHtmlForPerm.makeSplitPointClassesHtmls();
- MakeTopLevelHtmlForPerm.makeDependenciesTableHtmls();
- //make the shell last so we can display aggregate information here
+ // make the shell last so we can display aggregate information here
MakeTopLevelHtmlForPerm.makeHTMLShell(nameToCodeColl, nameToLitColl);
-
+
} catch (IOException e) {
throw new RuntimeException("Cannot open file. ", e);
}
}
-
/*
* assigns code to "all other code" if none of the special categories apply
*/
- private static void updateAllOtherCodeType(final HashMap<String, CodeCollection> nameToCodeColl){
- //all classes not in any of the other categories
- for (String className : GlobalInformation.classToPackage.keySet()){
- if ( (!nameToCodeColl.get("widget").classes.contains(className))&&
- (!nameToCodeColl.get("rpcUser").classes.contains(className))&&
- (!nameToCodeColl.get("rpcGwt").classes.contains(className))&&
- (!nameToCodeColl.get("rpcGen").classes.contains(className))&&
- (!nameToCodeColl.get("jre").classes.contains(className))&&
- (!nameToCodeColl.get("gwtLang").classes.contains(className))){
+ private static void updateAllOtherCodeType(
+ final HashMap<String, CodeCollection> nameToCodeColl) {
+ // all classes not in any of the other categories
+ for (String className : GlobalInformation.classToPackage.keySet()) {
+ if ((!nameToCodeColl.get("widget").classes.contains(className))
+ && (!nameToCodeColl.get("rpcUser").classes.contains(className))
+ && (!nameToCodeColl.get("rpcGwt").classes.contains(className))
+ && (!nameToCodeColl.get("rpcGen").classes.contains(className))
+ && (!nameToCodeColl.get("jre").classes.contains(className))
+ && (!nameToCodeColl.get("gwtLang").classes.contains(className))) {
nameToCodeColl.get("allOther").classes.add(className);
}
}
}
-
/*
- * unescape the JS snippets - in the XML file they are XML encoded for correct display, but this
- * will mess up the byte counts
+ * unescape the JS snippets - in the XML file they are XML encoded for correct
+ * display, but this will mess up the byte counts
*/
public static String unEscapeXml(String escaped) {
- String unescaped = escaped.replaceAll("&","\\&");
- unescaped = unescaped.replaceAll("<","\\<");
- unescaped = unescaped.replaceAll(">","\\>");
- unescaped = unescaped.replaceAll(""","\\\"");
- //escaped = escaped.replaceAll("\\n", "");
- unescaped = unescaped.replaceAll("'","\\'");
+ String unescaped = escaped.replaceAll("&", "\\&");
+ unescaped = unescaped.replaceAll("<", "\\<");
+ unescaped = unescaped.replaceAll(">", "\\>");
+ unescaped = unescaped.replaceAll(""", "\\\"");
+ // escaped = escaped.replaceAll("\\n", "");
+ unescaped = unescaped.replaceAll("'", "\\'");
return unescaped;
}
-
-
-
}
-
-
-
-
-
diff --git a/user/src/com/google/gwt/core/Core.gwt.xml b/user/src/com/google/gwt/core/Core.gwt.xml
index b207319..d88d528 100644
--- a/user/src/com/google/gwt/core/Core.gwt.xml
+++ b/user/src/com/google/gwt/core/Core.gwt.xml
@@ -21,14 +21,11 @@
<inherits name="com.google.gwt.dev.jjs.intrinsic.Intrinsic" />
<inherits name="com.google.gwt.emul.Emulation" />
- <define-linker name="soycReport" class="com.google.gwt.core.linker.soyc.SoycReportLinker" />
<define-linker name="sso" class="com.google.gwt.core.linker.SingleScriptLinker" />
<define-linker name="std" class="com.google.gwt.core.linker.IFrameLinker" />
<define-linker name="symbolMaps" class="com.google.gwt.core.linker.SymbolMapsLinker" />
<define-linker name="xs" class="com.google.gwt.core.linker.XSLinker" />
<add-linker name="std" />
- <add-linker name="soycReport" />
<add-linker name="symbolMaps" />
-
</module>