Esempio n. 1
0
  protected RunResult compile(String js1, String fileName1, String js2, String fileName2) {
    Compiler compiler = new Compiler();
    CompilerOptions options = getCompilerOptions();

    // Turn on IDE mode to get rid of optimizations.
    options.ideMode = true;

    JSSourceFile[] inputs = {JSSourceFile.fromCode(fileName1, js1)};

    if (js2 != null && fileName2 != null) {
      JSSourceFile[] multiple = {
        JSSourceFile.fromCode(fileName1, js1), JSSourceFile.fromCode(fileName2, js2)
      };
      inputs = multiple;
    }

    Result result = compiler.compile(EXTERNS, inputs, options);

    assertTrue("compilation failed", result.success);
    String source = compiler.toSource();

    StringBuilder sb = new StringBuilder();
    try {
      result.sourceMap.validate(true);
      result.sourceMap.appendTo(sb, "testcode");
    } catch (IOException e) {
      throw new RuntimeException("unexpected exception", e);
    }

    RunResult rr = new RunResult();
    rr.generatedSource = source;
    rr.sourceMap = result.sourceMap;
    rr.sourceMapFileContent = sb.toString();
    return rr;
  }
 private String runPass(String moduleName, String code) {
   Compiler compiler = new Compiler();
   Node root = compiler.parse(JSSourceFile.fromCode(moduleName, code));
   pass.process(null, root);
   CodeBuilder cb = new CodeBuilder();
   compiler.toSource(cb, 0, root);
   return cb.toString();
 }
Esempio n. 3
0
  /** core method */
  private void writeJsTo(Writer writer) throws IOException {
    Compiler compiler;
    CompilerOptions options;
    List<SourceFile> externals;
    List<SourceFile> sources;
    Result result;
    boolean first;
    int i;
    Node node;

    compiler = new Compiler(new LoggerErrorManager());
    options = new CompilerOptions();
    options.setOutputCharset(Engine.ENCODING);
    sources = new ArrayList<>();
    externals = new ArrayList<>();
    for (i = 0; i < nodes.size(); i++) {
      node = nodes.get(i);
      sources.add(
          SourceFile.fromCode(
              location(node) + /* to get unique names, which is checked by the compiler: */ "_" + i,
              readString(node)));
    }
    result = compiler.compile(externals, sources, options);
    if (!result.success) {
      if (result.errors.length < 1) {
        throw new IllegalStateException();
      }
      throw new IOException(
          result.errors[0].sourceName
              + ":"
              + result.errors[0].lineNumber
              + ":"
              + result.errors[0].description);
    }
    if (overallMinimize) {
      writer.write(compiler.toSource());
    } else {
      first = true;
      for (SourceFile source : sources) {
        if (first) {
          first = false;
        } else {
          writer.write(LF);
        }
        if (!overallMinimize) {
          writer.write(type.comment(source.getName()));
        }
        writer.write(source.getCode());
      }
    }
  }
Esempio n. 4
0
  public String getCompiledCode() {
    Preconditions.checkState(hasResult(), "Code has not been compiled yet");
    if (cachedCode != null) {
      return cachedCode;
    }

    int lineOffset = 1; // one line for the function wrapper
    StringBuffer prependBuffer = new StringBuffer();
    for (File prepend : config.getPrependInputs()) {
      try {
        String s = Files.toString(prepend);
        if (s != null) {
          String[] lines = s.split("\n");
          for (String line : lines) {
            prependBuffer.append(line);
            prependBuffer.append("\n");
            lineOffset++;
          }
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    compiler.setPrependedLineOffset(lineOffset);
    String compiledCode =
        prependBuffer.toString()
            + (inputJsConcatenatedInOrder != null
                ? inputJsConcatenatedInOrder
                : compiler.toSource());
    String outputWrapper = config.getOutputWrapper();
    if (outputWrapper != null) {
      String outputWrapperMarker = config.getOutputWrapperMarker();
      int pos = outputWrapper.indexOf(outputWrapperMarker);
      if (pos >= 0) {
        compiledCode =
            outputWrapper.substring(0, pos)
                + compiledCode
                + outputWrapper.substring(pos + outputWrapperMarker.length());
      } else {
        throw new RuntimeException(
            "output-wrapper did not contain placeholder: " + outputWrapperMarker);
      }
    }
    cachedCode = compiledCode;
    return compiledCode;
  }
 private String compile(HtmlLibrary library, ClosureOptimizationLevel opt, InputStream js)
     throws IOException {
   CompilationLevel compilationLevel = opt.toCompilationLevel();
   if (null == compilationLevel) {
     // return original input
     return IOUtils.toString(js);
   }
   SourceFile input = SourceFile.fromInputStream(getLibraryName(library), js);
   // TODO externs not supported, should avoid ADVANCED compilation
   SourceFile extern = SourceFile.fromCode("TODO", StringUtils.EMPTY);
   CompilerOptions options = new CompilerOptions();
   compilationLevel.setOptionsForCompilationLevel(options);
   // ES5 assumption to allow getters/setters
   options.setLanguageIn(CompilerOptions.LanguageMode.ECMASCRIPT5);
   Compiler compiler = new Compiler();
   compiler.compile(extern, input, options);
   return compiler.toSource();
 }
  /** @throws ExecutionException */
  public void run() throws ExecutionException {
    final Compiler compiler = new Compiler();
    final CompilerOptions options = new CompilerOptions();
    closureOptimization.setOptionsForCompilationLevel(options);

    final List<JSSourceFile> externs = Collections.emptyList();
    final List<JSSourceFile> sources = new ArrayList<JSSourceFile>();
    if (closurePreScript != null) {
      getLogger().info("Include PreScript:");
      sources.add(JSSourceFile.fromCode("closurePreScript.js", closurePreScript));
    }
    getFiles(sources);
    if (closurePostScript != null) {
      getLogger().info("Include PostScript:");
      sources.add(JSSourceFile.fromCode("closurePostScript.js", closurePostScript));
    }

    getLogger().info("Got " + sources.size() + " source files");
    final Result result = compiler.compile(externs, sources, options);
    if (!result.success) {
      throw new ExecutionException("Failed to compile scripts");
    }

    getLogger().info("Writing compiled js to " + closureTargetFile);
    try {
      FileUtils.forceMkdir(closureTargetFile.getParentFile());
      final FileWriter writer = new FileWriter(closureTargetFile);
      try {
        String preSource =
            closurePreScriptFile != null ? FileUtils.readFileToString(closurePreScriptFile) : "";
        String postSource =
            closurePostScriptFile != null ? FileUtils.readFileToString(closurePostScriptFile) : "";

        StringBuilder sb = new StringBuilder();
        sb.append(preSource).append(compiler.toSource()).append(postSource);
        writer.write(sb.toString());
      } finally {
        writer.close();
      }
    } catch (IOException e) {
      throw new ExecutionException("Failed to write target file: " + closureTargetFile, e);
    }
  }
Esempio n. 7
0
  public void execute() {
    if (this.outputFile == null) {
      throw new BuildException("outputFile attribute must be set");
    }

    Compiler.setLoggingLevel(Level.OFF);

    CompilerOptions options = createCompilerOptions();
    Compiler compiler = createCompiler(options);

    JSSourceFile[] externs = findExternFiles();
    JSSourceFile[] sources = findSourceFiles();

    log("Compiling " + sources.length + " file(s) with " + externs.length + " extern(s)");

    Result result = compiler.compile(externs, sources, options);
    if (result.success) {
      writeResult(compiler.toSource());
    } else {
      throw new BuildException("Compilation failed.");
    }
  }
  /**
   * Minimize the output using google closure compiler.
   *
   * @param output The input file to minimize.
   * @throws IOException If something goes wrong.
   * @throws MojoFailureException If something goes wrong.
   */
  private void minimize(final File output) throws IOException, MojoFailureException {
    final CompilerOptions options = new CompilerOptions();
    options.setCodingConvention(new ClosureCodingConvention());
    options.setOutputCharset("UTF-8");
    options.setWarningLevel(DiagnosticGroups.CHECK_VARIABLES, CheckLevel.WARNING);
    CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);

    Compiler.setLoggingLevel(Level.SEVERE);
    Compiler compiler = new Compiler();
    compiler.disableThreads();
    compiler.initOptions(options);

    Result result =
        compiler.compile(
            Collections.<SourceFile>emptyList(),
            Arrays.asList(SourceFile.fromFile(output)),
            options);
    if (result.success) {
      FileUtils.fileWrite(output, compiler.toSource());
    } else {
      JSError[] errors = result.errors;
      throw new MojoFailureException(errors[0].toString());
    }
  }
Esempio n. 9
0
  /**
   * This method always calls compiler.toSource(module), which means that it can be followed by a
   * call to compiler.getSourceMap().appendTo(writer, module), though
   * compiler.getSourceMap().reset() should be called immediately after when that is the case.
   *
   * <p>This method is sychronized in order to fix
   * http://code.google.com/p/plovr/issues/detail?id=31. The problem is that if two modules are
   * requested at the same time, it is often the case that compiler.toSource(module) is executing
   * for the second module while the source map is still being modified for the first module,
   * causing an IllegalStateException. Empirically, synchronizing this method appears to fix things,
   * though a more provably correct (and minimal) solution should be sought.
   */
  private synchronized String getCodeForModule(
      String moduleName,
      boolean isDebugMode,
      Function<String, String> moduleNameToUri,
      boolean resetSourceMap) {
    Preconditions.checkState(hasResult(), "Code has not been compiled yet");
    Preconditions.checkState(modules != null, "This compilation does not use modules");

    StringBuilder builder = new StringBuilder();
    ModuleConfig moduleConfig = config.getModuleConfig();
    String rootModule = moduleConfig.getRootModule();

    boolean isRootModule = rootModule.equals(moduleName);

    if (isRootModule) {
      // For the root module, prepend the following global variables:
      //
      // PLOVR_MODULE_INFO
      // PLOVR_MODULE_URIS
      // PLOVR_MODULE_USE_DEBUG_MODE
      //
      // Because the standard way to read these variables in the
      // application is:
      //
      // moduleLoader.setDebugMode(!!goog.global['PLOVR_MODULE_USE_DEBUG_MODE']);
      // moduleManager.setLoader(moduleLoader);
      // moduleManager.setAllModuleInfo(goog.global['PLOVR_MODULE_INFO']);
      // moduleManager.setModuleUris(goog.global['PLOVR_MODULE_URIS']);
      //
      // It is important that the PLOVR variables are guaranteed to be
      // global,
      // which (as much as it pains me) is why "var" is omitted.
      if (!moduleConfig.excludeModuleInfoFromRootModule()) {
        try {
          appendRootModuleInfo(builder, isDebugMode, moduleNameToUri);
        } catch (IOException e) {
          // This should not occur because data is being appended to
          // an
          // in-memory StringBuilder rather than a file.
          throw new RuntimeException(e);
        }
      }
    }

    int lineOffset = 0;

    JSModule module = nameToModule.get(moduleName);

    StringBuffer prependBuffer = new StringBuffer();
    if (isRootModule) {
      lineOffset++; // one line for the function wrapper
      for (File prepend : config.getPrependInputs()) {
        try {
          String s = Files.toString(prepend);
          if (s != null) {
            String[] lines = s.split("\n");
            for (String line : lines) {
              prependBuffer.append(line);
              prependBuffer.append("\n");
              lineOffset++;
            }
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    compiler.setPrependedLineOffset(lineOffset);
    String moduleCode = compiler.toSource(module);

    boolean hasGlobalScopeName =
        !Strings.isNullOrEmpty(config.getGlobalScopeName())
            && config.getCompilationMode() != CompilationMode.WHITESPACE;

    // Optionally wrap the module in an anonymous function, with the
    // requisite wrapper to make it work.
    if (hasGlobalScopeName) {
      if (isRootModule) {
        builder.append(prependBuffer.toString());
        // Initialize the global scope in the root module.
        builder.append(config.getGlobalScopeName());
        builder.append("={};");
      }
      builder.append("(function(");
      builder.append(Config.GLOBAL_SCOPE_NAME);
      // Including a newline makes the offset into the source map easier to calculate.
      builder.append("){\n");
    }
    builder.append(moduleCode);
    if (hasGlobalScopeName) {
      builder.append("})(");
      builder.append(config.getGlobalScopeName());
      builder.append(");");
    }

    if (resetSourceMap) {
      SourceMap sourceMap = compiler.getSourceMap();
      if (sourceMap != null) sourceMap.reset();
    }

    // http://code.google.com/p/closure-library/issues/detail?id=196
    // http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
    // non-root modules are loaded with eval, give it a sourceURL for better
    // debugging
    if (!isRootModule) {
      builder.append("\n//@ sourceURL=" + moduleNameToUri.apply(moduleName));
    }

    return builder.toString();
  }
  @Override
  public void execute() {
    if (this.outputFile == null) {
      throw new BuildException("outputFile attribute must be set");
    }

    Compiler.setLoggingLevel(Level.OFF);

    CompilerOptions options = createCompilerOptions();
    Compiler compiler = createCompiler(options);

    List<SourceFile> externs = findExternFiles();
    List<SourceFile> sources = findSourceFiles();

    if (isStale() || forceRecompile) {
      log("Compiling " + sources.size() + " file(s) with " + externs.size() + " extern(s)");

      Result result = compiler.compile(externs, sources, options);

      if (result.success) {
        StringBuilder source = new StringBuilder(compiler.toSource());

        if (this.outputWrapperFile != null) {
          try {
            this.outputWrapper = Files.toString(this.outputWrapperFile, UTF_8);
          } catch (Exception e) {
            throw new BuildException("Invalid output_wrapper_file specified.");
          }
        }

        if (this.outputWrapper != null) {
          int pos = -1;
          pos = this.outputWrapper.indexOf(CommandLineRunner.OUTPUT_MARKER);
          if (pos > -1) {
            String prefix = this.outputWrapper.substring(0, pos);
            source.insert(0, prefix);

            // end of outputWrapper
            int suffixStart = pos + CommandLineRunner.OUTPUT_MARKER.length();
            String suffix = this.outputWrapper.substring(suffixStart);
            source.append(suffix);
          } else {
            throw new BuildException(
                "Invalid output_wrapper specified. "
                    + "Missing '"
                    + CommandLineRunner.OUTPUT_MARKER
                    + "'.");
          }
        }

        if (result.sourceMap != null) {
          flushSourceMap(result.sourceMap);
          source.append(System.getProperty("line.separator"));
          source.append("//@ sourceMappingURL=" + sourceMapOutputFile.getName());
        }
        writeResult(source.toString());
      } else {
        throw new BuildException("Compilation failed.");
      }
    } else {
      log("None of the files changed. Compilation skipped.");
    }
  }