System.out.println("------------------------------------------------------------");
}
AST ast = unifiedAst.getFreshAst();
JProgram jprogram = ast.getJProgram();
JsProgram jsProgram = ast.getJsProgram();
JJSOptions options = unifiedAst.getOptions();
Map<StandardSymbolData, JsName> symbolTable = new TreeMap<StandardSymbolData, JsName>(
new SymbolData.ClassIdentComparator());
ResolveRebinds.exec(jprogram, rebindAnswers);
// (4) Optimize the normalized Java AST for each permutation.
if (options.isDraftCompile()) {
draftOptimize(jprogram);
} else {
optimize(options, jprogram);
}
// (5) "Normalize" the high-level Java tree into a lower-level tree more
// suited for JavaScript code generation. Don't go reordering these
// willy-nilly because there are some subtle interdependencies.
LongCastNormalizer.exec(jprogram);
JsoDevirtualizer.exec(jprogram);
CatchBlockNormalizer.exec(jprogram);
PostOptimizationCompoundAssignmentNormalizer.exec(jprogram);
LongEmulationNormalizer.exec(jprogram);
CastNormalizer.exec(jprogram, options.isCastCheckingDisabled());
ArrayNormalizer.exec(jprogram);
EqualityNormalizer.exec(jprogram);
// (6) Perform further post-normalization optimizations
// Prune everything
Pruner.exec(jprogram, false);
// (7) Generate a JavaScript code DOM from the Java type declarations
jprogram.typeOracle.recomputeAfterOptimizations();
JavaToJavaScriptMap map = GenerateJavaScriptAST.exec(jprogram, jsProgram,
options.getOutput(), symbolTable);
// (8) Normalize the JS AST.
// Fix invalid constructs created during JS AST gen.
JsNormalizer.exec(jsProgram);
// Resolve all unresolved JsNameRefs.
JsSymbolResolver.exec(jsProgram);
// Move all function definitions to a top-level scope, to reduce weirdness
EvalFunctionsAtTopScope.exec(jsProgram);
// (9) Optimize the JS AST.
if (options.isAggressivelyOptimize()) {
boolean didChange;
do {
if (Thread.interrupted()) {
throw new InterruptedException();
}
didChange = false;
// Remove unused functions, possible
didChange = JsStaticEval.exec(jsProgram) || didChange;
// Inline JavaScript function invocations
didChange = JsInliner.exec(jsProgram) || didChange;
// Remove unused functions, possible
didChange = JsUnusedFunctionRemover.exec(jsProgram) || didChange;
} while (didChange);
}
/*
* Creates new variables, must run before code splitter and namer.
*/
JsStackEmulator.exec(jsProgram, propertyOracles);
// (10) Split up the program into fragments
SyntheticArtifact dependencies = null;
if (options.isAggressivelyOptimize() && options.isRunAsyncEnabled()) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
CodeSplitter.exec(logger, jprogram, jsProgram, map,
chooseDependencyRecorder(options.isSoycEnabled(), baos));
if (baos.size() == 0 && options.isSoycEnabled()) {
recordNonSplitDependencies(jprogram, baos);
}
if (baos.size() > 0) {
dependencies = new SyntheticArtifact(SoycReportLinker.class,
"dependencies" + permutationId + ".xml.gz", baos.toByteArray());
}
}
// (10.5) Obfuscate
Map<JsName, String> obfuscateMap = Maps.create();
switch (options.getOutput()) {
case OBFUSCATED:
obfuscateMap = JsStringInterner.exec(jprogram, jsProgram);
JsObfuscateNamer.exec(jsProgram);
break;
case PRETTY:
// We don't intern strings in pretty mode to improve readability
JsPrettyNamer.exec(jsProgram);
break;
case DETAILED:
obfuscateMap = JsStringInterner.exec(jprogram, jsProgram);
JsVerboseNamer.exec(jsProgram);
break;
default:
throw new InternalCompilerException("Unknown output mode");
}
// (11) Perform any post-obfuscation normalizations.
// Work around an IE7 bug,
// http://code.google.com/p/google-web-toolkit/issues/detail?id=1440
// note, JsIEBlockTextTransformer now handles restructuring top level
// blocks, this class now handles non-top level blocks only.
SelectionProperty userAgentProperty = null;
for (PropertyOracle oracle : propertyOracles) {
try {
userAgentProperty = oracle.getSelectionProperty(logger, "user.agent");
} catch (BadPropertyValueException e) {
break;
}
}
// if user agent is known or ie6, split overly large blocks
boolean splitBlocks = userAgentProperty == null
|| ("ie6".equals(userAgentProperty.getCurrentValue()));
if (splitBlocks) {
JsIEBlockSizeVisitor.exec(jsProgram);
}
JsBreakUpLargeVarStatements.exec(jsProgram, propertyOracles);
// (12) Generate the final output text.
String[] js = new String[jsProgram.getFragmentCount()];
StatementRanges[] ranges = new StatementRanges[js.length];
SizeBreakdown[] sizeBreakdowns = options.isSoycEnabled()
? new SizeBreakdown[js.length] : null;
List<Map<Range, SourceInfo>> sourceInfoMaps = options.isSoycExtra()
? new ArrayList<Map<Range, SourceInfo>>() : null;