All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.dev.AnalyzeModule Maven / Gradle / Ivy

/*
 * 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.cfg.PropertyPermutations;
import com.google.gwt.dev.util.Memory;
import com.google.gwt.dev.util.Util;
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 java.io.File;
import java.io.IOException;

/**
 * Performs the first phase of compilation, generating the set of permutations
 * to compile and writing it out to a file.
 */
public class AnalyzeModule {

  /**
   * Mirror all the compiler options, in case this makes some difference in
   * module analysis.
   */
  @SuppressWarnings("serial")
  static class AnalyzeModuleOptionsImpl extends PrecompileTaskOptionsImpl implements
      AnalyzeModuleOptions {

    public AnalyzeModuleOptionsImpl() {
    }

    public AnalyzeModuleOptionsImpl(AnalyzeModuleOptions other) {
      copyFrom(other);
    }

    public void copyFrom(AnalyzeModuleOptions other) {
      super.copyFrom(other);
    }
  }

  static class ArgProcessor extends PrecompileTaskArgProcessor {
    public ArgProcessor(AnalyzeModuleOptions options) {
      super(options);
    }

    @Override
    protected String getName() {
      return AnalyzeModule.class.getName();
    }
  }

  private interface AnalyzeModuleOptions extends PrecompileTaskOptions {
    // This interface is here to support future options.
  }

  /**
   * The options passed to the AnalyzeModule step are saved here and passed
   * through to future steps.
   */
  static final String OPTIONS_FILENAME = "compilerOptions.ser";

  /**
   * Count of the maximum number of permutations in the module configuration.
   * Used to communicate the number of permutations defined in a module to an
   * external build tool.
   */
  static final String PERM_COUNT_FILENAME = "permCount.txt";

  /**
   * Performs a command-line analysis of the module with output to files for use
   * in further sharded build steps.
   */
  public static void main(String[] args) {
    Memory.initialize();
    SpeedTracerLogger.init();
    Event analyzeModuleEvent = SpeedTracerLogger.start(CompilerEventType.ANALYZE_MODULE);
    final AnalyzeModuleOptions options = new AnalyzeModuleOptionsImpl();
    if (new ArgProcessor(options).processArgs(args)) {
      CompileTask task = new CompileTask() {
        @Override
        public boolean run(TreeLogger logger) throws UnableToCompleteException {
          return new AnalyzeModule(options).run(logger);
        }
      };
      CompileTaskRunner.runWithAppropriateLogger(options, task);
    }
    analyzeModuleEvent.end();
  }

  /**
   * Loads the AnalyzeModule.OPTIONS_FILENAME data.
   *
   * Silently returns null if the file is not found or another problem is
   * encountered reading the file.
   */
  public static PrecompileTaskOptions readAnalyzeModuleOptionsFile(
      TreeLogger logger, File compilerWorkDir) {
    File optionsFile = new File(compilerWorkDir, AnalyzeModule.OPTIONS_FILENAME);
    PrecompileTaskOptions precompilationOptions = null;
    try {
      precompilationOptions = Util.readFileAsObject(optionsFile,
          PrecompileTaskOptions.class);
    } catch (IOException e) {
      if (logger.isLoggable(TreeLogger.DEBUG)) {
        logger.log(TreeLogger.DEBUG, "Failed to read " + optionsFile
            + "\nHas AnalyzeModule been run?  Falling back.", e);
      }
      return null;
    } catch (ClassNotFoundException e) {
      logger.log(TreeLogger.ERROR, "Failed to read " + optionsFile, e);
      return null;
    }
    return precompilationOptions;
  }

  private final AnalyzeModuleOptionsImpl options;

  private final CompilerContext compilerContext;

  public AnalyzeModule(AnalyzeModuleOptions options) {
    this.options = new AnalyzeModuleOptionsImpl(options);
    compilerContext = new CompilerContext.Builder().options(options).build();
  }

  public boolean run(TreeLogger logger) throws UnableToCompleteException {
    for (String moduleName : options.getModuleNames()) {
      File compilerWorkDir = options.getCompilerWorkDir(moduleName);
      Util.recursiveDelete(compilerWorkDir, true);
      // No need to check mkdirs result because an IOException will occur anyway
      compilerWorkDir.mkdirs();

      ModuleDef module =
          ModuleDefLoader.loadFromClassPath(logger, compilerContext, moduleName);
      if (logger.isLoggable(TreeLogger.INFO)) {
        logger.log(TreeLogger.INFO, "Analyzing module " + module.getName());
      }

      /*
       * Count the permutations to expose to external build tools performing a
       * sharded compile.
       */
      int numPermutations = new PropertyPermutations(module.getProperties(),
          module.getActiveLinkerNames()).collapseProperties().size();
      Util.writeStringAsFile(logger, new File(compilerWorkDir,
          AnalyzeModule.PERM_COUNT_FILENAME), String.valueOf(numPermutations));
      Util.writeObjectAsFile(logger, new File(compilerWorkDir,
          AnalyzeModule.OPTIONS_FILENAME), options);

      // TODO(zundel): Serializing the ModuleDef structure would save time in
      // subsequent steps.

      // TODO(zundel): Building the initial type oracle in this step would save
      // cputime when the precompile step is sharded.
    }

    return true;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy