Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.dev.jjs;
import com.google.gwt.core.ext.BadPropertyValueException;
import com.google.gwt.core.ext.PropertyOracle;
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.CompilationMetricsArtifact;
import com.google.gwt.core.ext.linker.EmittedArtifact;
import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.ModuleMetricsArtifact;
import com.google.gwt.core.ext.linker.PrecompilationMetricsArtifact;
import com.google.gwt.core.ext.linker.StatementRanges;
import com.google.gwt.core.ext.linker.SymbolData;
import com.google.gwt.core.ext.linker.SyntheticArtifact;
import com.google.gwt.core.ext.linker.impl.StandardSymbolData;
import com.google.gwt.core.ext.soyc.Range;
import com.google.gwt.core.ext.soyc.SourceMapRecorder;
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.CompilerContext;
import com.google.gwt.dev.Permutation;
import com.google.gwt.dev.PrecompileTaskOptions;
import com.google.gwt.dev.cfg.ConfigurationProperty;
import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.javac.CompilationProblemReporter;
import com.google.gwt.dev.javac.typemodel.TypeOracle;
import com.google.gwt.dev.jdt.RebindPermutationOracle;
import com.google.gwt.dev.jjs.UnifiedAst.AST;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JBinaryOperation;
import com.google.gwt.dev.jjs.ast.JBinaryOperator;
import com.google.gwt.dev.jjs.ast.JBlock;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JGwtCreate;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodBody;
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JNode;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReboundEntryPoint;
import com.google.gwt.dev.jjs.ast.JStatement;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.jjs.impl.ArrayNormalizer;
import com.google.gwt.dev.jjs.impl.AssertionNormalizer;
import com.google.gwt.dev.jjs.impl.AssertionRemover;
import com.google.gwt.dev.jjs.impl.AstDumper;
import com.google.gwt.dev.jjs.impl.CastNormalizer;
import com.google.gwt.dev.jjs.impl.CatchBlockNormalizer;
import com.google.gwt.dev.jjs.impl.ControlFlowAnalyzer;
import com.google.gwt.dev.jjs.impl.DeadCodeElimination;
import com.google.gwt.dev.jjs.impl.EnumOrdinalizer;
import com.google.gwt.dev.jjs.impl.EqualityNormalizer;
import com.google.gwt.dev.jjs.impl.Finalizer;
import com.google.gwt.dev.jjs.impl.FixAssignmentsToUnboxOrCast;
import com.google.gwt.dev.jjs.impl.GenerateJavaScriptAST;
import com.google.gwt.dev.jjs.impl.HandleCrossFragmentReferences;
import com.google.gwt.dev.jjs.impl.ImplementClassLiteralsAsFields;
import com.google.gwt.dev.jjs.impl.JavaToJavaScriptMap;
import com.google.gwt.dev.jjs.impl.JsAbstractTextTransformer;
import com.google.gwt.dev.jjs.impl.JsFunctionClusterer;
import com.google.gwt.dev.jjs.impl.JsIEBlockTextTransformer;
import com.google.gwt.dev.jjs.impl.JsoDevirtualizer;
import com.google.gwt.dev.jjs.impl.LongCastNormalizer;
import com.google.gwt.dev.jjs.impl.LongEmulationNormalizer;
import com.google.gwt.dev.jjs.impl.MakeCallsStatic;
import com.google.gwt.dev.jjs.impl.MethodCallTightener;
import com.google.gwt.dev.jjs.impl.MethodInliner;
import com.google.gwt.dev.jjs.impl.OptimizerStats;
import com.google.gwt.dev.jjs.impl.PostOptimizationCompoundAssignmentNormalizer;
import com.google.gwt.dev.jjs.impl.Pruner;
import com.google.gwt.dev.jjs.impl.RecordRebinds;
import com.google.gwt.dev.jjs.impl.RemoveEmptySuperCalls;
import com.google.gwt.dev.jjs.impl.ReplaceGetClassOverrides;
import com.google.gwt.dev.jjs.impl.ResolveRebinds;
import com.google.gwt.dev.jjs.impl.SameParameterValueOptimizer;
import com.google.gwt.dev.jjs.impl.SourceInfoCorrelator;
import com.google.gwt.dev.jjs.impl.TypeTightener;
import com.google.gwt.dev.jjs.impl.UnifyAst;
import com.google.gwt.dev.jjs.impl.VerifySymbolMap;
import com.google.gwt.dev.jjs.impl.codesplitter.CodeSplitter;
import com.google.gwt.dev.jjs.impl.codesplitter.CodeSplitters;
import com.google.gwt.dev.jjs.impl.codesplitter.MultipleDependencyGraphRecorder;
import com.google.gwt.dev.jjs.impl.codesplitter.ReplaceRunAsyncs;
import com.google.gwt.dev.jjs.impl.gflow.DataflowOptimizer;
import com.google.gwt.dev.js.BaselineCoverageGatherer;
import com.google.gwt.dev.js.ClosureJsRunner;
import com.google.gwt.dev.js.CoverageInstrumentor;
import com.google.gwt.dev.js.EvalFunctionsAtTopScope;
import com.google.gwt.dev.js.FreshNameGenerator;
import com.google.gwt.dev.js.JsBreakUpLargeVarStatements;
import com.google.gwt.dev.js.JsCoerceIntShift;
import com.google.gwt.dev.js.JsDuplicateCaseFolder;
import com.google.gwt.dev.js.JsDuplicateFunctionRemover;
import com.google.gwt.dev.js.JsIEBlockSizeVisitor;
import com.google.gwt.dev.js.JsInliner;
import com.google.gwt.dev.js.JsNormalizer;
import com.google.gwt.dev.js.JsObfuscateNamer;
import com.google.gwt.dev.js.JsPrettyNamer;
import com.google.gwt.dev.js.JsReportGenerationVisitor;
import com.google.gwt.dev.js.JsSourceGenerationVisitorWithSizeBreakdown;
import com.google.gwt.dev.js.JsStackEmulator;
import com.google.gwt.dev.js.JsStaticEval;
import com.google.gwt.dev.js.JsStringInterner;
import com.google.gwt.dev.js.JsSymbolResolver;
import com.google.gwt.dev.js.JsUnusedFunctionRemover;
import com.google.gwt.dev.js.JsVerboseNamer;
import com.google.gwt.dev.js.SizeBreakdown;
import com.google.gwt.dev.js.ast.JsContext;
import com.google.gwt.dev.js.ast.JsForIn;
import com.google.gwt.dev.js.ast.JsFunction;
import com.google.gwt.dev.js.ast.JsLabel;
import com.google.gwt.dev.js.ast.JsName;
import com.google.gwt.dev.js.ast.JsNameOf;
import com.google.gwt.dev.js.ast.JsNameRef;
import com.google.gwt.dev.js.ast.JsNode;
import com.google.gwt.dev.js.ast.JsParameter;
import com.google.gwt.dev.js.ast.JsProgram;
import com.google.gwt.dev.js.ast.JsVars;
import com.google.gwt.dev.js.ast.JsVisitor;
import com.google.gwt.dev.util.DefaultTextOutput;
import com.google.gwt.dev.util.Empty;
import com.google.gwt.dev.util.Memory;
import com.google.gwt.dev.util.Pair;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.arg.OptionOptimize;
import com.google.gwt.dev.util.collect.Lists;
import com.google.gwt.dev.util.collect.Maps;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.soyc.SoycDashboard;
import com.google.gwt.soyc.io.ArtifactsOutputDirectory;
import com.google.gwt.thirdparty.guava.common.collect.Multimap;
import org.xml.sax.SAXException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.zip.GZIPInputStream;
import javax.xml.parsers.ParserConfigurationException;
/**
* Compiles the Java JProgram representation into its corresponding
* JavaScript source.
*/
public class JavaToJavaScriptCompiler {
private static class PermutationResultImpl implements PermutationResult {
private final ArtifactSet artifacts = new ArtifactSet();
private final byte[][] js;
private final Permutation permutation;
private final byte[] serializedSymbolMap;
private final StatementRanges[] statementRanges;
public PermutationResultImpl(String[] js, Permutation permutation, SymbolData[] symbolMap,
StatementRanges[] statementRanges) {
byte[][] bytes = new byte[js.length][];
for (int i = 0; i < js.length; ++i) {
bytes[i] = Util.getBytes(js[i]);
}
this.js = bytes;
this.permutation = permutation;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Util.writeObjectToStream(baos, (Object) symbolMap);
this.serializedSymbolMap = baos.toByteArray();
} catch (IOException e) {
throw new RuntimeException("Should never happen with in-memory stream", e);
}
this.statementRanges = statementRanges;
}
@Override
public void addArtifacts(Collection extends Artifact>> newArtifacts) {
this.artifacts.addAll(newArtifacts);
}
@Override
public ArtifactSet getArtifacts() {
return artifacts;
}
@Override
public byte[][] getJs() {
return js;
}
@Override
public Permutation getPermutation() {
return permutation;
}
@Override
public byte[] getSerializedSymbolMap() {
return serializedSymbolMap;
}
@Override
public StatementRanges[] getStatementRanges() {
return statementRanges;
}
}
private static class TreeStatistics extends JVisitor {
private int nodeCount = 0;
public int getNodeCount() {
return nodeCount;
}
@Override
public boolean visit(JNode x, Context ctx) {
nodeCount++;
return true;
}
}
private static final String ENUM_NAME_OBFUSCATION_PROPERTY = "compiler.enum.obfuscate.names";
/**
* Continuing to apply optimizations till the rate of change reaches this value causes the AST to
* reach a fixed point.
*/
private static final int FIXED_POINT_CHANGE_RATE = 0;
/**
* Ending optimization passes when the rate of change has reached this value results in
* gaining nearly all of the impact while avoiding the long tail of costly but low-impact passes.
*/
private static final float EFFICIENT_CHANGE_RATE = 0.01f;
/**
* Limits the number of optimization passes against the possible danger of an AST that does not
* converge.
*/
private static final int MAX_PASSES = 100;
/**
* Compiles a particular permutation, based on a precompiled unified AST.
*
* @param logger the logger to use
* @param compilerContext shared read only compiler state
* @param unifiedAst of stitched together per-type ASTs
* @param permutation the permutation to compile
* @return the output JavaScript
* @throws UnableToCompleteException if an error other than {@link OutOfMemoryError} occurs
*/
public static PermutationResult compilePermutation(TreeLogger logger,
CompilerContext compilerContext, UnifiedAst unifiedAst, Permutation permutation)
throws UnableToCompleteException {
JJSOptions options = unifiedAst.getOptions();
long startTimeMilliseconds = System.currentTimeMillis();
Event jjsCompilePermutationEvent =
SpeedTracerLogger.start(CompilerEventType.JJS_COMPILE_PERMUTATION, "name", permutation
.prettyPrint());
InternalCompilerException.preload();
PropertyOracle[] propertyOracles = permutation.getPropertyOracles();
int permutationId = permutation.getId();
if (logger.isLoggable(TreeLogger.INFO)) {
logger.log(TreeLogger.INFO, "Compiling permutation " + permutationId + "...");
}
long permStart = System.currentTimeMillis();
try {
if (JProgram.isTracingEnabled()) {
System.out.println("-------------------------------------------------------------");
System.out.println("| (new permutation) |");
System.out.println("-------------------------------------------------------------");
System.out.println("Properties: " + permutation.prettyPrint());
}
AST ast = unifiedAst.getFreshAst();
JProgram jprogram = ast.getJProgram();
JsProgram jsProgram = ast.getJsProgram();
Map symbolTable =
new TreeMap(new SymbolData.ClassIdentComparator());
ResolveRebinds.exec(jprogram, permutation.getOrderedRebindAnswers());
// Traverse the AST to figure out which lines are instrumentable for
// coverage. This has to happen before optimizations because functions might
// be optimized out; we want those marked as "not executed", not "not
// instrumentable".
Multimap instrumentableLines = null;
if (System.getProperty("gwt.coverage") != null) {
instrumentableLines = BaselineCoverageGatherer.exec(jprogram);
}
// (4) Optimize the normalized Java AST for each permutation.
int optimizationLevel = options.getOptimizationLevel();
if (optimizationLevel == OptionOptimize.OPTIMIZE_LEVEL_DRAFT) {
draftOptimize(jprogram);
} else {
optimize(options, jprogram);
}
RemoveEmptySuperCalls.exec(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.
JsoDevirtualizer.exec(jprogram);
CatchBlockNormalizer.exec(jprogram);
PostOptimizationCompoundAssignmentNormalizer.exec(jprogram);
LongCastNormalizer.exec(jprogram);
LongEmulationNormalizer.exec(jprogram);
CastNormalizer.exec(jprogram, options.isCastCheckingDisabled());
ArrayNormalizer.exec(jprogram, options.isCastCheckingDisabled());
EqualityNormalizer.exec(jprogram);
// (6) Perform further post-normalization optimizations
// Prune everything
Pruner.exec(jprogram, false);
// prune all Object.getClass() overrides and replace with inline field ref
ReplaceGetClassOverrides.exec(jprogram);
// (7) Generate a JavaScript code DOM from the Java type declarations
jprogram.typeOracle.recomputeAfterOptimizations();
Pair extends JavaToJavaScriptMap, Set> genAstResult =
GenerateJavaScriptAST.exec(jprogram, jsProgram, options.getOutput(), symbolTable,
propertyOracles);
JavaToJavaScriptMap jjsmap = genAstResult.getLeft();
// (8) Normalize the JS AST.
// Fix invalid constructs created during JS AST gen.
JsNormalizer.exec(jsProgram);
/*
* If coverage is enabled, instrument the AST to record location info.
*/
if (instrumentableLines != null) {
CoverageInstrumentor.exec(jsProgram, instrumentableLines);
}
// Resolve all unresolved JsNameRefs.
JsSymbolResolver.exec(jsProgram);
// Move all function definitions to a top-level scope, to reduce weirdness
EvalFunctionsAtTopScope.exec(jsProgram, jjsmap);
// (9) Optimize the JS AST.
if (optimizationLevel > OptionOptimize.OPTIMIZE_LEVEL_DRAFT) {
optimizeJs(options, jsProgram, genAstResult.getRight());
/*
* Coalesce redundant labels in switch statements.
*/
JsDuplicateCaseFolder.exec(jsProgram);
}
/*
* Creates new variables, must run before code splitter and namer.
*/
JsStackEmulator.exec(jprogram, jsProgram, propertyOracles, jjsmap);
/*
* Work around Safari 5 bug by rewriting a >> b as ~~a >> b.
*
* No shifts may be generated after this point.
*/
JsCoerceIntShift.exec(jsProgram, logger, propertyOracles);
// (10) Split up the program into fragments
SyntheticArtifact dependencies = null;
if (options.isRunAsyncEnabled()) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int expectedFragmentCount = options.getFragmentCount();
// -1 is the default value, we trap 0 just in case (0 is not a legal value in any case)
if (expectedFragmentCount <= 0) {
// Fragment count not set check fragments merge.
int numberOfMerges = options.getFragmentsMerge();
if (numberOfMerges > 0) {
// + 1 for left over, + 1 for initial gave us the total number
// of fragments without splitting.
expectedFragmentCount = Math.max(0,
jprogram.getRunAsyncs().size() + 2 - numberOfMerges);
}
}
int minFragmentSize = findIntegerConfigurationProperty(propertyOracles, logger,
CodeSplitters.MIN_FRAGMENT_SIZE, 0);
CodeSplitter.exec(logger, jprogram, jsProgram, jjsmap, expectedFragmentCount,
minFragmentSize, 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());
}
}
// detect if browser is ie6 or not known
boolean isIE6orUnknown = findBooleanProperty(propertyOracles, logger, "user.agent", "ie6",
true, false, true);
boolean isSourceMapsEnabled = findBooleanProperty(propertyOracles, logger,
"compiler.useSourceMaps", "true", true, false, false);
// (10.5) Obfuscate
Map obfuscateMap = Maps.create();
switch (options.getOutput()) {
case OBFUSCATED:
obfuscateMap = JsStringInterner.exec(jprogram, jsProgram, isIE6orUnknown);
FreshNameGenerator freshNameGenerator = JsObfuscateNamer.exec(jsProgram, propertyOracles);
if (options.shouldRemoveDuplicateFunctions() &&
JsStackEmulator.getStackMode(propertyOracles) == JsStackEmulator.StackMode.STRIP) {
JsDuplicateFunctionRemover.exec(jsProgram, freshNameGenerator);
}
break;
case PRETTY:
// We don't intern strings in pretty mode to improve readability
JsPrettyNamer.exec(jsProgram, propertyOracles);
break;
case DETAILED:
obfuscateMap = JsStringInterner.exec(jprogram, jsProgram, isIE6orUnknown);
JsVerboseNamer.exec(jsProgram, propertyOracles);
break;
default:
throw new InternalCompilerException("Unknown output mode");
}
// (10.8) Handle cross-island references.
// No new JsNames or references to JSNames can be introduced after this
// point.
HandleCrossFragmentReferences.exec(logger, jsProgram, propertyOracles);
// Verify that SymbolMap is somewhat close to being complete.
VerifySymbolMap.exec(jsProgram, jjsmap, symbolTable);
// (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.
boolean splitBlocks = isIE6orUnknown;
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() || options.isCompilerMetricsEnabled()
? new SizeBreakdown[js.length] : null;
List