blob: f7230de75ea2e8a99003b16797869a8101c5ec67 [file] [log] [blame]
/*
* Copyright 2010 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;
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.cfg.ModuleDef;
import com.google.gwt.dev.cfg.ModuleDefLoader;
import com.google.gwt.dev.jjs.JavaToJavaScriptCompiler;
import com.google.gwt.dev.jjs.PermutationResult;
import com.google.gwt.dev.util.PerfCounter;
import com.google.gwt.dev.util.arg.ArgHandlerPerm;
import com.google.gwt.dev.util.arg.OptionPerm;
import java.io.File;
import java.util.List;
/**
* Performs the second phase of compilation, converting one of the Precompile's
* serialized AST files into JavaScript outputs.
*/
public class CompileOnePerm {
/**
* Options for CompilePerm.
*/
public interface CompileOnePermOptions extends PrecompileTaskOptions, OptionPerm {
}
static class ArgProcessor extends PrecompileTaskArgProcessor {
public ArgProcessor(CompileOnePermOptions options) {
super(options);
registerHandler(new ArgHandlerPerm(options));
}
@Override
protected String getName() {
return CompileOnePerm.class.getName();
}
}
/**
* Concrete class to implement compiler perm options.
*/
static class CompileOnePermOptionsImpl extends PrecompileTaskOptionsImpl
implements CompileOnePermOptions {
private int permToCompile = -1;
public CompileOnePermOptionsImpl() {
}
public CompileOnePermOptionsImpl(CompileOnePermOptions other) {
copyFrom(other);
}
public void copyFrom(CompileOnePermOptions other) {
super.copyFrom(other);
setPermToCompile(other.getPermToCompile());
}
@Override
public int getPermToCompile() {
return permToCompile;
}
@Override
public void setPermToCompile(int permToCompile) {
this.permToCompile = permToCompile;
}
}
public static void main(String[] args) {
int exitCode = -1;
/*
* NOTE: main always exits with a call to System.exit to terminate any
* non-daemon threads that were started in Generators. Typically, this is to
* shutdown AWT related threads, since the contract for their termination is
* still implementation-dependent.
*/
final CompileOnePermOptions options = new CompileOnePermOptionsImpl();
if (new ArgProcessor(options).processArgs(args)) {
CompileTask task = new CompileTask() {
@Override
public boolean run(TreeLogger logger) throws UnableToCompleteException {
return new CompileOnePerm(options).run(logger);
}
};
if (CompileTaskRunner.runWithAppropriateLogger(options, task)) {
// Exit w/ success code.
exitCode = 0;
}
}
PerfCounter.print();
System.exit(exitCode);
}
/**
* Return the filename corresponding to the given permutation number,
* one-based.
*/
static File makePermFilename(File compilerWorkDir, int permNumber) {
return new File(compilerWorkDir, "permutation-" + permNumber + ".js");
}
/**
* Run Compile where precompilation occurred previously on sharded steps of
* Precompile. There will be a different serialized AST file named
* permutation-*.ser, one per permutation.
*
* @param logger tree logger
* @param moduleName Name of the GWT module with the entry point
* @param permId permutations to compile
* @param compilerWorkDir directory where work files are stored
*
* @return <code>true</code> if compilation succeeds
*/
private static boolean compileSpecificPermutation(TreeLogger logger,
String moduleName, PrecompileTaskOptions precompilationOptions, int permId,
File compilerWorkDir) throws UnableToCompleteException {
CompilerContext.Builder compilerContextBuilder = new CompilerContext.Builder();
CompilerContext compilerContext = compilerContextBuilder.options(precompilationOptions).build();
ModuleDef module = ModuleDefLoader.loadFromClassPath(logger, compilerContext, moduleName);
compilerContext = compilerContextBuilder.module(module).build();
logger = logger.branch(TreeLogger.INFO, "Compiling permutation " + permId);
File precompilationFile = new File(compilerWorkDir,
PrecompileOnePerm.getPrecompileFilename(permId));
Precompilation precompilation = (Precompilation) CompilePerms.readPrecompilationFile(
logger, precompilationFile);
// Choose the permutation that goes with this precompilation
Permutation[] subPerms = CompilePerms.selectPermutationsForPrecompilation(
new int[]{permId}, precompilation);
assert subPerms.length == 1;
PermutationResult permResult =
JavaToJavaScriptCompiler.compilePermutation(precompilation.getUnifiedAst(), logger,
compilerContext, subPerms[0]);
Link.linkOnePermutationToJar(logger, module, compilerContext.getPublicResourceOracle(),
precompilation.getGeneratedArtifacts(), permResult, makePermFilename(
compilerWorkDir, permId), precompilationOptions);
return true;
}
private final CompileOnePermOptionsImpl options;
public CompileOnePerm(CompileOnePermOptions options) {
this.options = new CompileOnePermOptionsImpl(options);
}
public boolean run(TreeLogger logger) throws UnableToCompleteException {
List<String> moduleNames = options.getModuleNames();
if (moduleNames.size() != 1) {
logger.log(TreeLogger.ERROR, "Expected a single module name.");
return false;
}
int permToRun = options.getPermToCompile();
if (permToRun < 0) {
logger.log(TreeLogger.ERROR,
"Expected argument -perm to specify the permutation to compile.");
return false;
}
String moduleName = moduleNames.get(0);
File compilerWorkDir = options.getCompilerWorkDir(moduleName);
// Look for the sentinel file that indicates that this compilation already
// has a precompilation result from a previous Precompile step.
PrecompileTaskOptions precompilationOptions = AnalyzeModule.readAnalyzeModuleOptionsFile(
logger, compilerWorkDir);
if (precompilationOptions == null) {
logger.log(TreeLogger.ERROR, "Could not read file "
+ AnalyzeModule.OPTIONS_FILENAME + " output from AnalyzeModule step.");
return false;
}
return compileSpecificPermutation(logger, moduleName,
precompilationOptions, permToRun, compilerWorkDir);
}
}