Refactor SOYC to produce artifacts more directly.
Patch by: spoon
Review by: me
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6498 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
deleted file mode 100644
index 982499a..0000000
--- a/dev/core/src/com/google/gwt/core/ext/linker/CompilationAnalysis.java
+++ /dev/null
@@ -1,127 +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.linker;
-
-import com.google.gwt.core.ext.Linker;
-import com.google.gwt.core.ext.linker.impl.StandardCompilationAnalysis.SoycArtifact;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Represents analysis data for a CompilationResult.
- */
-public abstract class CompilationAnalysis extends Artifact<CompilationAnalysis> {
-
- protected CompilationAnalysis(Class<? extends Linker> linkerType) {
- super(linkerType);
- }
-
- /**
- * @return a file of dependencies
- */
- public abstract EmittedArtifact getDepFile();
-
- /**
- * @return a file with detailed story information
- */
- public abstract EmittedArtifact getDetailedStoriesFile();
-
- /**
- * Files containing the HTML dashboard.
- */
-
- public abstract List<SoycArtifact> getReportFiles();
-
- /**
- * @return a file of size maps
- */
- public abstract EmittedArtifact getSizeMapsFile();
-
- /**
- * @return a file of split points
- */
- public abstract EmittedArtifact getSplitPointsFile();
-
- @Override
- public final int hashCode() {
- int code = 37;
- for (EmittedArtifact file : allFiles()) {
- if (file == null) {
- code = code * 17 + 37;
- } else {
- code = code * 17 + file.getPartialPath().hashCode();
- }
- }
- return code;
- }
-
- @Override
- protected final int compareToComparableArtifact(CompilationAnalysis o) {
- LinkedList<EmittedArtifact> myFiles = new LinkedList<EmittedArtifact>(
- allFiles());
- LinkedList<EmittedArtifact> otherFiles = new LinkedList<EmittedArtifact>(
- o.allFiles());
-
- while (!myFiles.isEmpty()) {
- if (otherFiles.isEmpty()) {
- return 1;
- }
-
- EmittedArtifact myFile = myFiles.removeFirst();
- EmittedArtifact otherFile = otherFiles.removeFirst();
- if (myFile == null && otherFile == null) {
- continue;
- }
- if (myFile == null && otherFile != null) {
- return -1;
- }
- if (myFile != null && otherFile == null) {
- return 1;
- }
- assert myFile != null;
- assert otherFile != null;
-
- int fileCompare = myFile.getPartialPath().compareTo(
- otherFile.getPartialPath());
- if (fileCompare != 0) {
- return fileCompare;
- }
- }
-
- if (!otherFiles.isEmpty()) {
- return -1;
- }
-
- return 0;
- }
-
- @Override
- protected final Class<CompilationAnalysis> getComparableArtifactType() {
- return CompilationAnalysis.class;
- }
-
- private List<EmittedArtifact> allFiles() {
- List<EmittedArtifact> files = new ArrayList<EmittedArtifact>();
- files.add(getSplitPointsFile());
- files.add(getDepFile());
- files.add(getSizeMapsFile());
- files.add(getDetailedStoriesFile());
- files.addAll(getReportFiles());
- return files;
- }
-}
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
deleted file mode 100644
index 327c5ba..0000000
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationAnalysis.java
+++ /dev/null
@@ -1,105 +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.linker.impl;
-
-import com.google.gwt.core.ext.linker.CompilationAnalysis;
-import com.google.gwt.core.ext.linker.SyntheticArtifact;
-import com.google.gwt.core.linker.SoycReportLinker;
-
-import java.util.List;
-
-/**
- * An implementation of CompilationAnalysis. This class transforms SourceInfos
- * and related data into an API suitable for public consumption via the Linker
- * API.
- */
-public class StandardCompilationAnalysis extends CompilationAnalysis {
-
- /**
- * A SOYC artifact. The existence of this class is an implementation detail.
- */
- public static class SoycArtifact extends SyntheticArtifact {
- public SoycArtifact(String partialPath, byte[] bytes) {
- super(SoycReportLinker.class, partialPath, bytes);
- setPrivate(true);
- }
- }
-
- /**
- * File containing method-level control-flow dependencies (corresponding to
- * the current report).
- */
- private SoycArtifact depFile;
-
- /**
- * File containing detailed story information.
- */
- private SoycArtifact detailedStoriesFile;
-
- /**
- * Files containing the HTML dashboard.
- */
- private List<SoycArtifact> reportFiles;
-
- /**
- * File containing size maps.
- */
- private SoycArtifact sizeMapsFile;
-
- /**
- * File containing split points.
- */
- private SoycArtifact splitPointsFile;
-
- /**
- * Constructed by PermutationCompiler.
- */
- public StandardCompilationAnalysis(SoycArtifact dependencies,
- SoycArtifact sizeMaps, SoycArtifact splitPoints,
- SoycArtifact detailedStories, List<SoycArtifact> reportFiles) {
- super(StandardLinkerContext.class);
- this.depFile = dependencies;
- this.sizeMapsFile = sizeMaps;
- this.splitPointsFile = splitPoints;
- this.detailedStoriesFile = detailedStories;
- this.reportFiles = reportFiles;
- }
-
- @Override
- public SoycArtifact getDepFile() {
- return depFile;
- }
-
- @Override
- public SoycArtifact getDetailedStoriesFile() {
- return detailedStoriesFile;
- }
-
- @Override
- public List<SoycArtifact> getReportFiles() {
- return reportFiles;
- }
-
- @Override
- public SoycArtifact getSizeMapsFile() {
- return sizeMapsFile;
- }
-
- @Override
- public SoycArtifact getSplitPointsFile() {
- return splitPointsFile;
- }
-}
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/package-info.java b/dev/core/src/com/google/gwt/core/ext/soyc/package-info.java
index 5cb0045..50693fb 100644
--- a/dev/core/src/com/google/gwt/core/ext/soyc/package-info.java
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/package-info.java
@@ -16,8 +16,8 @@
/**
* This package contains interfaces that provide access to
- * "Story of Your Compile" information. When the compiler is run with analysis
- * turned on, these types are available to Linkers via
- * {@link com.google.gwt.core.ext.linker.CompilationAnalysis} artifacts.
+ * "Story of Your Compile" information. When the compiler is run with detailed
+ * analysis turned on, these types are available via XML files in the extras
+ * output.
*/
package com.google.gwt.core.ext.soyc;
\ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/core/linker/SoycReportLinker.java b/dev/core/src/com/google/gwt/core/linker/SoycReportLinker.java
index 2f63ff1..2843250 100644
--- a/dev/core/src/com/google/gwt/core/linker/SoycReportLinker.java
+++ b/dev/core/src/com/google/gwt/core/linker/SoycReportLinker.java
@@ -23,8 +23,8 @@
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.LinkerOrder.Order;
-import com.google.gwt.core.ext.linker.impl.StandardCompilationAnalysis;
import com.google.gwt.soyc.SoycDashboard;
import com.google.gwt.soyc.io.ArtifactsOutputDirectory;
@@ -33,7 +33,7 @@
import java.util.TreeMap;
/**
- * Converts SOYC report files into emitted private artifacts.
+ * Generates the top-level report files for a compile report.
*/
@LinkerOrder(Order.POST)
public class SoycReportLinker extends Linker {
@@ -46,38 +46,22 @@
@Override
public ArtifactSet link(TreeLogger logger, LinkerContext context,
ArtifactSet artifacts) throws UnableToCompleteException {
+ if (!includesReports(artifacts)) {
+ return artifacts;
+ }
+
ArtifactSet results = new ArtifactSet(artifacts);
- boolean foundReports = false;
- for (StandardCompilationAnalysis soycFiles : artifacts.find(StandardCompilationAnalysis.class)) {
- if (soycFiles.getDepFile() != null) {
- results.add(soycFiles.getDepFile());
- }
- if (soycFiles.getSizeMapsFile() != null) {
- results.add(soycFiles.getSizeMapsFile());
- }
- if (soycFiles.getDetailedStoriesFile() != null) {
- results.add(soycFiles.getDetailedStoriesFile());
- }
- results.add(soycFiles.getSplitPointsFile());
- if (!soycFiles.getReportFiles().isEmpty()) {
- results.addAll(soycFiles.getReportFiles());
- foundReports = true;
- }
+ // Run the final step of the dashboard to generate top-level files.
+ ArtifactsOutputDirectory out = new ArtifactsOutputDirectory();
+ try {
+ new SoycDashboard(out).generateCrossPermutationFiles(extractPermutationDescriptions(artifacts));
+ } catch (IOException e) {
+ logger.log(TreeLogger.ERROR,
+ "Error while generating a Story of Your Compile", e);
}
+ results.addAll(out.getArtifacts());
- if (foundReports) {
- // run the final step of the dashboard to generate top-level files
- ArtifactsOutputDirectory out = new ArtifactsOutputDirectory();
- try {
- new SoycDashboard(out).generateCrossPermutationFiles(extractPermutationDescriptions(artifacts));
- } catch (IOException e) {
- logger.log(TreeLogger.ERROR,
- "Error while generating a Story of Your Compile", e);
- e.printStackTrace();
- }
- results.addAll(out.getArtifacts());
- }
return results;
}
@@ -98,4 +82,14 @@
return permDescriptions;
}
+
+ private boolean includesReports(ArtifactSet artifacts) {
+ for (SyntheticArtifact art : artifacts.find(SyntheticArtifact.class)) {
+ if (art.getPartialPath().startsWith(
+ ArtifactsOutputDirectory.COMPILE_REPORT_DIRECTORY + "/")) {
+ return true;
+ }
+ }
+ return false;
+ }
}
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 a6d177d..99d34a3 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -19,18 +19,19 @@
import com.google.gwt.core.ext.SelectionProperty;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.linker.Artifact;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.EmittedArtifact;
import com.google.gwt.core.ext.linker.StatementRanges;
import com.google.gwt.core.ext.linker.SymbolData;
-import com.google.gwt.core.ext.linker.impl.StandardCompilationAnalysis;
+import com.google.gwt.core.ext.linker.SyntheticArtifact;
import com.google.gwt.core.ext.linker.impl.StandardSymbolData;
-import com.google.gwt.core.ext.linker.impl.StandardCompilationAnalysis.SoycArtifact;
import com.google.gwt.core.ext.soyc.Range;
import com.google.gwt.core.ext.soyc.impl.DependencyRecorder;
import com.google.gwt.core.ext.soyc.impl.SizeMapRecorder;
import com.google.gwt.core.ext.soyc.impl.SplitPointRecorder;
import com.google.gwt.core.ext.soyc.impl.StoryRecorder;
+import com.google.gwt.core.linker.SoycReportLinker;
import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.jdt.RebindPermutationOracle;
import com.google.gwt.dev.jdt.WebModeCompilerFrontEnd;
@@ -111,7 +112,6 @@
import com.google.gwt.dev.util.PerfLogger;
import com.google.gwt.dev.util.TextOutput;
import com.google.gwt.dev.util.Util;
-import com.google.gwt.dev.util.collect.Lists;
import com.google.gwt.dev.util.collect.Maps;
import com.google.gwt.soyc.SoycDashboard;
import com.google.gwt.soyc.io.ArtifactsOutputDirectory;
@@ -128,6 +128,7 @@
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -290,7 +291,7 @@
JsStackEmulator.exec(jsProgram, propertyOracles);
// (10) Split up the program into fragments
- SoycArtifact dependencies = null;
+ SyntheticArtifact dependencies = null;
if (options.isAggressivelyOptimize() && options.isRunAsyncEnabled()) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
CodeSplitter.exec(logger, jprogram, jsProgram, map,
@@ -299,8 +300,8 @@
recordNonSplitDependencies(jprogram, baos);
}
if (baos.size() > 0) {
- dependencies = new SoycArtifact("dependencies" + permutationId
- + ".xml.gz", baos.toByteArray());
+ dependencies = new SyntheticArtifact(SoycReportLinker.class,
+ "dependencies" + permutationId + ".xml.gz", baos.toByteArray());
}
}
@@ -357,9 +358,9 @@
PermutationResult toReturn = new PermutationResultImpl(js,
makeSymbolMap(symbolTable), ranges, permutationId);
- toReturn.getArtifacts().add(
- makeSoycArtifact(logger, permutationId, jprogram, js, sizeBreakdowns,
- sourceInfoMaps, dependencies, map, obfuscateMap));
+ toReturn.getArtifacts().addAll(
+ makeSoycArtifacts(logger, permutationId, jprogram, js,
+ sizeBreakdowns, sourceInfoMaps, dependencies, map, obfuscateMap));
logger.log(TreeLogger.TRACE, "Permutation took "
+ (System.currentTimeMillis() - permStart) + " ms");
@@ -938,32 +939,36 @@
}
}
- private static StandardCompilationAnalysis makeSoycArtifact(
+ private static Collection<? extends Artifact<?>> makeSoycArtifacts(
TreeLogger logger, int permutationId, JProgram jprogram, String[] js,
SizeBreakdown[] sizeBreakdowns,
- List<Map<Range, SourceInfo>> sourceInfoMaps, SoycArtifact dependencies,
- JavaToJavaScriptMap jjsmap, Map<JsName, String> obfuscateMap)
- throws IOException, UnableToCompleteException {
+ List<Map<Range, SourceInfo>> sourceInfoMaps,
+ SyntheticArtifact dependencies, JavaToJavaScriptMap jjsmap,
+ Map<JsName, String> obfuscateMap) throws IOException,
+ UnableToCompleteException {
+ List<Artifact<?>> soycArtifacts = new ArrayList<Artifact<?>>();
+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PerfLogger.start("Recording compile report output");
PerfLogger.start("Record split points");
SplitPointRecorder.recordSplitPoints(jprogram, baos, logger);
- SoycArtifact splitPoints = new SoycArtifact("splitPoints" + permutationId
- + ".xml.gz", baos.toByteArray());
+ SyntheticArtifact splitPoints = new SyntheticArtifact(
+ SoycReportLinker.class, "splitPoints" + permutationId + ".xml.gz",
+ baos.toByteArray());
+ soycArtifacts.add(splitPoints);
PerfLogger.end();
- SoycArtifact sizeMaps = null;
- SoycArtifact detailedStories = null;
-
+ SyntheticArtifact sizeMaps = null;
if (sizeBreakdowns != null) {
PerfLogger.start("Record size map");
baos.reset();
SizeMapRecorder.recordMap(logger, baos, sizeBreakdowns, jjsmap,
obfuscateMap);
- sizeMaps = new SoycArtifact("stories" + permutationId + ".xml.gz",
- baos.toByteArray());
+ sizeMaps = new SyntheticArtifact(SoycReportLinker.class, "stories"
+ + permutationId + ".xml.gz", baos.toByteArray());
+ soycArtifacts.add(sizeMaps);
PerfLogger.end();
}
@@ -971,14 +976,17 @@
PerfLogger.start("Record detailed stories");
baos.reset();
StoryRecorder.recordStories(logger, baos, sourceInfoMaps, js);
- detailedStories = new SoycArtifact("detailedStories" + permutationId
- + ".xml.gz", baos.toByteArray());
+ soycArtifacts.add(new SyntheticArtifact(SoycReportLinker.class,
+ "detailedStories" + permutationId + ".xml.gz", baos.toByteArray()));
PerfLogger.end();
}
+ if (dependencies != null) {
+ soycArtifacts.add(dependencies);
+ }
+
PerfLogger.end();
- List<SoycArtifact> reportArtifacts = Lists.create();
if (sizeBreakdowns != null) {
PerfLogger.start("Generating compile report");
ArtifactsOutputDirectory outDir = new ArtifactsOutputDirectory();
@@ -1002,12 +1010,11 @@
e);
}
dashboard.generateForOnePermutation();
- reportArtifacts = outDir.getArtifacts();
+ soycArtifacts.addAll(outDir.getArtifacts());
PerfLogger.end();
}
- return new StandardCompilationAnalysis(dependencies, sizeMaps, splitPoints,
- detailedStories, reportArtifacts);
+ return soycArtifacts;
}
/**
diff --git a/dev/core/src/com/google/gwt/soyc/io/ArtifactsOutputDirectory.java b/dev/core/src/com/google/gwt/soyc/io/ArtifactsOutputDirectory.java
index fb774b7..1b34036 100644
--- a/dev/core/src/com/google/gwt/soyc/io/ArtifactsOutputDirectory.java
+++ b/dev/core/src/com/google/gwt/soyc/io/ArtifactsOutputDirectory.java
@@ -15,7 +15,8 @@
*/
package com.google.gwt.soyc.io;
-import com.google.gwt.core.ext.linker.impl.StandardCompilationAnalysis.SoycArtifact;
+import com.google.gwt.core.ext.linker.SyntheticArtifact;
+import com.google.gwt.core.linker.SoycReportLinker;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -28,13 +29,13 @@
* artifacts.
*/
public class ArtifactsOutputDirectory implements OutputDirectory {
+ public static final String COMPILE_REPORT_DIRECTORY = "compile-report";
+
/**
* An in-memory output stream. When it is closed, its contents are saved to an
* artifact.
*/
private class OutputStreamForArtifact extends OutputStream {
- private static final String OUTPUT_DIRECTORY_NAME = "compile-report";
-
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
private boolean closed = false;
private final String path;
@@ -47,8 +48,9 @@
public void close() {
if (!closed) {
closed = true;
- SoycArtifact newArtifact = new SoycArtifact(OUTPUT_DIRECTORY_NAME + "/"
- + path, baos.toByteArray());
+ SyntheticArtifact newArtifact = new SyntheticArtifact(
+ SoycReportLinker.class, COMPILE_REPORT_DIRECTORY + "/" + path,
+ baos.toByteArray());
newArtifact.setPrivate(false);
artifacts.add(newArtifact);
baos = null;
@@ -71,12 +73,12 @@
}
}
- private List<SoycArtifact> artifacts = new ArrayList<SoycArtifact>();
+ private List<SyntheticArtifact> artifacts = new ArrayList<SyntheticArtifact>();
/**
* Return the list of artifacts that have been written so far.
*/
- public List<SoycArtifact> getArtifacts() {
+ public List<SyntheticArtifact> getArtifacts() {
return artifacts;
}