| /* |
| * 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 { |
| ModuleDef module = ModuleDefLoader.loadFromClassPath(logger, moduleName); |
| |
| CompilerContext compilerContext = new CompilerContext.Builder() |
| .options(precompilationOptions).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); |
| } |
| } |