Esempio n. 1
0
  /**
   * Creates a dummy output directory without compiling the module. Either this method or {@link
   * #precompile} should be called first.
   */
  synchronized Job.Result initWithoutPrecompile(TreeLogger logger)
      throws UnableToCompleteException {

    long startTime = System.currentTimeMillis();
    CompileDir compileDir = outboxDir.makeCompileDir(logger);
    TreeLogger compileLogger = makeCompileLogger(compileDir, logger);
    ModuleDef module;
    try {
      module = loadModule(compileLogger);

      logger.log(TreeLogger.INFO, "Loading Java files in " + inputModuleName + ".");
      CompilerOptions loadOptions = new CompilerOptionsImpl(compileDir, inputModuleName, options);
      compilerContext = compilerContextBuilder.options(loadOptions).unitCache(unitCache).build();

      // Loads and parses all the Java files in the GWT application using the JDT.
      // (This is warmup to make compiling faster later; we stop at this point to avoid
      // needing to know the binding properties.)
      module.getCompilationState(compileLogger, compilerContext);

      setUpCompileDir(compileDir, module, compileLogger);
      if (launcherDir != null) {
        launcherDir.update(module, compileDir, compileLogger);
      }

      outputModuleName.set(module.getName());
    } finally {
      // Make the compile log available no matter what happens.
      lastBuild.set(compileDir);
    }

    long elapsedTime = System.currentTimeMillis() - startTime;
    compileLogger.log(TreeLogger.Type.INFO, "Module setup completed in " + elapsedTime + " ms");

    return new Result(compileDir, module.getName(), null);
  }
Esempio n. 2
0
  public void testLoadFromLibraryGroup()
      throws UnableToCompleteException, IOException, IncompatibleLibraryVersionException {
    // Create the library zip file.
    File zipFile = File.createTempFile("FooLib", ".gwtlib");
    zipFile.deleteOnExit();

    // Put data in the library and save it.
    ZipLibraryWriter zipLibraryWriter = new ZipLibraryWriter(zipFile.getPath());
    zipLibraryWriter.setLibraryName("FooLib");
    MockResource userXmlResource =
        new MockResource("com/google/gwt/user/User.gwt.xml") {
          @Override
          public CharSequence getContent() {
            return "<module></module>";
          }
        };
    zipLibraryWriter.addBuildResource(userXmlResource);
    zipLibraryWriter.write();

    // Read data back from disk.
    ZipLibrary zipLibrary = new ZipLibrary(zipFile.getPath());

    // Prepare the LibraryGroup and ResourceLoader.
    compilerContext =
        compilerContextBuilder
            .libraryGroup(
                LibraryGroup.fromLibraries(Lists.<Library>newArrayList(zipLibrary), false))
            .build();
    ResourceLoader resourceLoader =
        ResourceLoaders.wrap(new URLClassLoader(new URL[] {zipFile.toURL()}, null));

    // Will throw an exception if com.google.gwt.user.User can't be found and parsed.
    ModuleDefLoader.loadFromResources(
        TreeLogger.NULL, compilerContext, "com.google.gwt.user.User", resourceLoader, false);
  }
Esempio n. 3
0
  public void testWritesTargetLibraryProperties() throws UnableToCompleteException {
    compilerContext = compilerContextBuilder.compileMonolithic(false).build();
    ModuleDef libraryOneModule =
        ModuleDefLoader.loadFromClassPath(
            TreeLogger.NULL,
            compilerContext,
            "com.google.gwt.dev.cfg.testdata.separate.libraryone.LibraryOne",
            false);

    // Library one sees all defined values for the "libraryTwoProperty" binding property and knows
    // which one was defined in this target library.
    for (BindingProperty bindingProperty :
        libraryOneModule.getProperties().getBindingProperties()) {
      if (!bindingProperty.getName().equals("libraryTwoProperty")) {
        continue;
      }
      assertEquals(
          Sets.newHashSet(bindingProperty.getDefinedValues()),
          Sets.newHashSet("yes", "no", "maybe"));
      assertEquals(
          Sets.newHashSet(bindingProperty.getTargetLibraryDefinedValues()),
          Sets.newHashSet("maybe"));
    }

    // Library one added a new defined value of "maybe" for the "libraryTwoProperty" binding
    // property.
    assertEquals(
        Sets.newHashSet(
            mockLibraryWriter.getNewBindingPropertyValuesByName().get("libraryTwoProperty")),
        Sets.newHashSet("maybe"));

    // Library one sees all defined values for the "libraryTwoConfigProperty" property and knows
    // which one was defined in this target library.
    for (ConfigurationProperty configurationProperty :
        libraryOneModule.getProperties().getConfigurationProperties()) {
      if (!configurationProperty.getName().equals("libraryTwoConfigProperty")) {
        continue;
      }
      assertEquals(Sets.newHashSet(configurationProperty.getValues()), Sets.newHashSet("false"));
      assertEquals(
          Sets.newHashSet(configurationProperty.getTargetLibraryValues()),
          Sets.newHashSet("false"));
    }

    // Library one added a new defined value of "maybe" for the "libraryTwoConfigProperty"
    // property.
    assertEquals(
        Sets.newHashSet(
            mockLibraryWriter
                .getNewConfigurationPropertyValuesByName()
                .get("libraryTwoConfigProperty")),
        Sets.newHashSet("false"));
  }
Esempio n. 4
0
  public void testSeparateLibraryName() throws UnableToCompleteException {
    compilerContext = compilerContextBuilder.compileMonolithic(false).build();
    ModuleDefLoader.loadFromClassPath(
        TreeLogger.NULL,
        compilerContext,
        "com.google.gwt.dev.cfg.testdata.separate.libraryone.LibraryOne",
        false);

    assertEquals(
        "com.google.gwt.dev.cfg.testdata.separate.libraryone.LibraryOne",
        mockLibraryWriter.getLibraryName());
  }
Esempio n. 5
0
 public void testSeparateRootFilesetFail() {
   compilerContext = compilerContextBuilder.compileMonolithic(false).build();
   TreeLogger logger = TreeLogger.NULL;
   try {
     ModuleDefLoader.loadFromClassPath(
         logger,
         compilerContext,
         "com.google.gwt.dev.cfg.testdata.separate.filesetone.FileSetOne",
         false);
     fail("Expected a fileset loaded as the root of a module tree to fail, but it didn't.");
   } catch (UnableToCompleteException e) {
     // Expected behavior.
   }
 }
Esempio n. 6
0
 Recompiler(
     OutboxDir outboxDir,
     LauncherDir launcherDir,
     String inputModuleName,
     Options options,
     UnitCache unitCache,
     MinimalRebuildCacheManager minimalRebuildCacheManager) {
   this.outboxDir = outboxDir;
   this.launcherDir = launcherDir;
   this.inputModuleName = inputModuleName;
   this.options = options;
   this.unitCache = unitCache;
   this.minimalRebuildCacheManager = minimalRebuildCacheManager;
   this.serverPrefix = options.getPreferredHost() + ":" + options.getPort();
   compilerContext = compilerContextBuilder.build();
 }
Esempio n. 7
0
  public void testSeparateModuleReferences() throws UnableToCompleteException {
    compilerContext = compilerContextBuilder.compileMonolithic(false).build();
    ModuleDef libraryOneModule =
        ModuleDefLoader.loadFromClassPath(
            TreeLogger.NULL,
            compilerContext,
            "com.google.gwt.dev.cfg.testdata.separate.libraryone.LibraryOne",
            false);

    // The module sees itself and it's direct fileset module as "target" modules.
    assertEquals(
        Sets.newHashSet(
            "com.google.gwt.dev.cfg.testdata.separate.libraryone.LibraryOne",
            "com.google.gwt.dev.cfg.testdata.separate.filesetone.FileSetOne"),
        libraryOneModule.getTargetLibraryModuleNames());
    // The module sees the referenced library module as a "library" module.
    assertEquals(
        Sets.newHashSet("com.google.gwt.dev.cfg.testdata.separate.librarytwo.LibraryTwo"),
        libraryOneModule.getExternalLibraryModuleNames());
  }
Esempio n. 8
0
  public void testSeparateLibraryModuleReferences() throws UnableToCompleteException {
    compilerContext = compilerContextBuilder.compileMonolithic(false).build();
    ModuleDefLoader.loadFromClassPath(
        TreeLogger.NULL,
        compilerContext,
        "com.google.gwt.dev.cfg.testdata.separate.libraryone.LibraryOne",
        false);

    // The library writer was given the module and it's direct fileset module xml files as build
    // resources.
    assertEquals(
        Sets.newHashSet(
            "com/google/gwt/dev/cfg/testdata/separate/filesetone/FileSetOne.gwt.xml",
            "com/google/gwt/dev/cfg/testdata/separate/libraryone/LibraryOne.gwt.xml"),
        mockLibraryWriter.getBuildResourcePaths());
    // The library writer was given LibraryTwo as a dependency library.
    assertEquals(
        Sets.newHashSet("com.google.gwt.dev.cfg.testdata.separate.librarytwo.LibraryTwo"),
        mockLibraryWriter.getDependencyLibraryNames());
  }
Esempio n. 9
0
  public void testSeparateModuleResourcesLibraryOne() throws UnableToCompleteException {
    compilerContext = compilerContextBuilder.compileMonolithic(false).build();
    ModuleDef libraryOneModule =
        ModuleDefLoader.loadFromClassPath(
            TreeLogger.NULL,
            compilerContext,
            "com.google.gwt.dev.cfg.testdata.separate.libraryone.LibraryOne",
            false);

    // Includes own source.
    assertNotNull(
        libraryOneModule.findSourceFile(
            "com/google/gwt/dev/cfg/testdata/separate/libraryone/client/LibraryOne.java"));
    // Cascades to include the subtree of fileset sources.
    assertNotNull(
        libraryOneModule.findSourceFile(
            "com/google/gwt/dev/cfg/testdata/separate/filesetone/client/FileSetOne.java"));
    // Does not include source from referenced libraries.
    assertNull(
        libraryOneModule.findSourceFile(
            "com/google/gwt/dev/cfg/testdata/separate/librarytwo/client/LibraryTwo.java"));
  }
Esempio n. 10
0
  /**
   * Calls the GWT compiler with the appropriate settings. Side-effect: a MinimalRebuildCache for
   * the current binding properties will be found or created.
   *
   * @param job used for reporting progress. (Its result will not be set.)
   * @return a non-error Job.Result if successful.
   * @throws UnableToCompleteException for compile failures.
   */
  private Job.Result compile(Job job) throws UnableToCompleteException {

    assert job.wasSubmitted();

    if (compilesDone == 0) {
      System.setProperty("java.awt.headless", "true");
      if (System.getProperty("gwt.speedtracerlog") == null) {
        System.setProperty(
            "gwt.speedtracerlog", outboxDir.getSpeedTracerLogFile().getAbsolutePath());
      }
      compilerContext = compilerContextBuilder.unitCache(unitCache).build();
    }

    long startTime = System.currentTimeMillis();
    int compileId = ++compilesDone;
    CompileDir compileDir = outboxDir.makeCompileDir(job.getLogger());
    TreeLogger compileLogger = makeCompileLogger(compileDir, job.getLogger());
    try {
      job.onStarted(compileId, compileDir);
      boolean success = doCompile(compileLogger, compileDir, job);
      if (!success) {
        compileLogger.log(TreeLogger.Type.ERROR, "Compiler returned false");
        throw new UnableToCompleteException();
      }
    } finally {
      // Make the error log available no matter what happens
      lastBuild.set(compileDir);
    }

    long elapsedTime = System.currentTimeMillis() - startTime;
    compileLogger.log(
        TreeLogger.Type.INFO,
        String.format("%.3fs total -- Compile completed", elapsedTime / 1000d));

    return new Result(publishedCompileDir, outputModuleName.get(), null);
  }
Esempio n. 11
0
 @Override
 protected void setUp() throws Exception {
   super.setUp();
   ModuleDefLoader.getModulesCache().clear();
   compilerContext = compilerContextBuilder.libraryWriter(mockLibraryWriter).build();
 }
Esempio n. 12
0
  /** Loads the module and configures it for SuperDevMode. (Does not restrict permutations.) */
  private ModuleDef loadModule(TreeLogger logger) throws UnableToCompleteException {

    // make sure we get the latest version of any modified jar
    ZipFileClassPathEntry.clearCache();
    ResourceOracleImpl.clearCache();

    ResourceLoader resources = ResourceLoaders.forClassLoader(Thread.currentThread());
    resources = ResourceLoaders.forPathAndFallback(options.getSourcePath(), resources);
    this.resourceLoader.set(resources);

    // ModuleDefLoader.loadFromResources() checks for modified .gwt.xml files.
    ModuleDef moduleDef =
        ModuleDefLoader.loadFromResources(
            logger, compilerContext, inputModuleName, resources, true);
    compilerContext = compilerContextBuilder.module(moduleDef).build();

    // Undo all permutation restriction customizations from previous compiles.
    for (BindingProperty bindingProperty : moduleDef.getProperties().getBindingProperties()) {
      String[] allowedValues = bindingProperty.getAllowedValues(bindingProperty.getRootCondition());
      bindingProperty.setRootGeneratedValues(allowedValues);
    }

    // A snapshot of the module's configuration before we modified it.
    ConfigProps config = new ConfigProps(moduleDef);

    // We need a cross-site linker. Automatically replace the default linker.
    if (IFrameLinker.class.isAssignableFrom(moduleDef.getActivePrimaryLinker())) {
      moduleDef.addLinker("xsiframe");
    }

    // Check that we have a compatible linker.
    Class<? extends Linker> linker = moduleDef.getActivePrimaryLinker();
    if (!CrossSiteIframeLinker.class.isAssignableFrom(linker)) {
      logger.log(
          TreeLogger.ERROR,
          "linkers other than CrossSiteIFrameLinker aren't supported. Found: " + linker.getName());
      throw new UnableToCompleteException();
    }

    // Deactivate precompress linker.
    if (moduleDef.deactivateLinker("precompress")) {
      logger.log(TreeLogger.WARN, "Deactivated PrecompressLinker");
    }

    // Print a nice error if the superdevmode hook isn't present
    if (config.getStrings("devModeRedirectEnabled").isEmpty()) {
      throw new RuntimeException(
          "devModeRedirectEnabled isn't set for module: " + moduleDef.getName());
    }

    // Disable the redirect hook here to make sure we don't have an infinite loop.
    // (There is another check in the JavaScript, but just in case.)
    overrideConfig(moduleDef, "devModeRedirectEnabled", "false");

    // Turn off "installCode" if it's on because it makes debugging harder.
    // (If it's already off, don't change anything.)
    if (config.getBoolean("installCode", true)) {
      overrideConfig(moduleDef, "installCode", "false");
      // Make sure installScriptJs is set to the default for compiling without installCode.
      overrideConfig(
          moduleDef,
          "installScriptJs",
          "com/google/gwt/core/ext/linker/impl/installScriptDirect.js");
    }

    // override computeScriptBase.js to enable the "Compile" button
    overrideConfig(
        moduleDef, "computeScriptBaseJs", "com/google/gwt/dev/codeserver/computeScriptBase.js");
    // Fix bug with SDM and Chrome 24+ where //@ sourceURL directives cause X-SourceMap header to be
    // ignored
    // Frustratingly, Chrome won't canonicalize a relative URL
    overrideConfig(
        moduleDef,
        "includeSourceMapUrl",
        "http://" + serverPrefix + SourceHandler.sourceMapLocationTemplate(moduleDef.getName()));

    // If present, set some config properties back to defaults.
    // (Needed for Google's server-side linker.)
    maybeOverrideConfig(moduleDef, "includeBootstrapInPrimaryFragment", "false");
    maybeOverrideConfig(
        moduleDef, "permutationsJs", "com/google/gwt/core/ext/linker/impl/permutations.js");
    maybeOverrideConfig(
        moduleDef, "propertiesJs", "com/google/gwt/core/ext/linker/impl/properties.js");

    if (options.isIncrementalCompileEnabled()) {
      // CSSResourceGenerator needs to produce stable, unique naming for its input.
      // Currently on default settings CssResourceGenerator's obfuscation depends on
      // whole world knowledge and thus will produce collision in obfuscated mode, since in
      // incremental compiles that information is not available.
      //
      // TODO(dankurka): Once we do proper stable hashing of classes in CssResourceGenerator, we
      // can probably replace / remove this.
      maybeOverrideConfig(moduleDef, "CssResource.style", "stable");
    }

    overrideBinding(moduleDef, "compiler.useSourceMaps", "true");
    overrideBinding(moduleDef, "compiler.useSymbolMaps", "false");
    overrideBinding(moduleDef, "superdevmode", "on");

    return moduleDef;
  }
Esempio n. 13
0
  private boolean doCompile(TreeLogger compileLogger, CompileDir compileDir, Job job)
      throws UnableToCompleteException {

    job.onProgress("Loading modules");

    CompilerOptions loadOptions = new CompilerOptionsImpl(compileDir, inputModuleName, options);
    compilerContext = compilerContextBuilder.options(loadOptions).build();

    ModuleDef module = loadModule(compileLogger);
    if (!Compiler.maybeRestrictProperties(compileLogger, module, loadOptions.getProperties())) {
      return false;
    }

    // We need to generate the stub before restricting permutations
    String recompileJs = generateModuleRecompileJs(module, compileLogger);

    Map<String, String> bindingProperties =
        restrictPermutations(compileLogger, module, job.getBindingProperties());

    // Propagates module rename.
    String newModuleName = module.getName();
    outputModuleName.set(newModuleName);

    // Check if we can skip the compile altogether.
    InputSummary input = new InputSummary(bindingProperties, module);
    if (input.equals(lastBuildInput)) {
      compileLogger.log(Type.INFO, "skipped compile because no input files have changed");
      job.setCompileStrategy(CompileStrategy.SKIPPED);
      return true;
    }
    // Force a recompile if we don't succeed.
    lastBuildInput = null;

    job.onProgress("Compiling");
    // TODO: use speed tracer to get more compiler events?

    CompilerOptions runOptions = new CompilerOptionsImpl(compileDir, newModuleName, options);
    compilerContext = compilerContextBuilder.options(runOptions).build();

    MinimalRebuildCache minimalRebuildCache = new NullRebuildCache();
    if (options.isIncrementalCompileEnabled()) {
      // Returns a copy of the intended cache, which is safe to modify in this compile.
      minimalRebuildCache = minimalRebuildCacheManager.getCache(inputModuleName, bindingProperties);
    }
    job.setCompileStrategy(
        minimalRebuildCache.isPopulated() ? CompileStrategy.INCREMENTAL : CompileStrategy.FULL);

    boolean success = new Compiler(runOptions, minimalRebuildCache).run(compileLogger, module);
    if (success) {
      publishedCompileDir = compileDir;
      lastBuildInput = input;
      if (options.isIncrementalCompileEnabled()) {
        minimalRebuildCacheManager.putCache(
            inputModuleName, bindingProperties, minimalRebuildCache);
      }
      String moduleName = outputModuleName.get();
      writeRecompileNoCacheJs(
          new File(publishedCompileDir.getWarDir(), moduleName),
          moduleName,
          recompileJs,
          compileLogger);
      if (launcherDir != null) {
        launcherDir.update(module, compileDir, compileLogger);
      }
    }

    return success;
  }