diff options
Diffstat (limited to 'examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ScalaJSClosureOptimizer.scala')
-rw-r--r-- | examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ScalaJSClosureOptimizer.scala | 216 |
1 files changed, 0 insertions, 216 deletions
diff --git a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ScalaJSClosureOptimizer.scala b/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ScalaJSClosureOptimizer.scala deleted file mode 100644 index 146b2b8..0000000 --- a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ScalaJSClosureOptimizer.scala +++ /dev/null @@ -1,216 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ __ ____ Scala.js tools ** -** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** -** /____/\___/_/ |_/____/_/ | |__/ /____/ ** -** |/____/ ** -\* */ - - -package scala.scalajs.tools.optimizer - -import scala.scalajs.tools.sem.Semantics -import scala.scalajs.tools.classpath._ -import scala.scalajs.tools.logging._ -import scala.scalajs.tools.io._ -import scala.scalajs.tools.corelib.CoreJSLibs - -import com.google.javascript.jscomp.{ - SourceFile => ClosureSource, - Compiler => ClosureCompiler, - CompilerOptions => ClosureOptions, - _ -} -import scala.collection.JavaConverters._ -import scala.collection.immutable.{Seq, Traversable} - -import java.net.URI - -/** Scala.js Closure optimizer: does advanced optimizations with Closure. */ -class ScalaJSClosureOptimizer(semantics: Semantics) { - import ScalaJSClosureOptimizer._ - - private def toClosureSource(file: VirtualJSFile) = - ClosureSource.fromReader(file.toURI.toString(), file.reader) - - private def toClosureInput(file: VirtualJSFile) = - new CompilerInput(toClosureSource(file)) - - /** Fully optimizes an [[IRClasspath]] by asking the ScalaJSOptimizer to - * emit a closure AST and then compiling this AST directly - */ - def optimizeCP(optimizer: ScalaJSOptimizer, - inputs: Inputs[ScalaJSOptimizer.Inputs[IRClasspath]], - outCfg: OutputConfig, logger: Logger): LinkedClasspath = { - - val cp = inputs.input.input - - CacheUtils.cached(cp.version, outCfg.output, outCfg.cache) { - logger.info(s"Full Optimizing ${outCfg.output.path}") - - val irFastOptInput = - inputs.input.copy(input = inputs.input.input.scalaJSIR) - val irFullOptInput = inputs.copy(input = irFastOptInput) - - optimizeIR(optimizer, irFullOptInput, outCfg, logger) - } - - new LinkedClasspath(cp.jsLibs, outCfg.output, cp.requiresDOM, cp.version) - } - - def optimizeIR(optimizer: ScalaJSOptimizer, - inputs: Inputs[ScalaJSOptimizer.Inputs[Traversable[VirtualScalaJSIRFile]]], - outCfg: OutputConfig, logger: Logger): Unit = { - - // Build Closure IR via ScalaJSOptimizer - val builder = new ClosureAstBuilder(outCfg.relativizeSourceMapBase) - - optimizer.optimizeIR(inputs.input, outCfg, builder, logger) - - // Build a Closure JSModule which includes the core libs - val module = new JSModule("Scala.js") - - for (lib <- CoreJSLibs.libs(semantics)) - module.add(toClosureInput(lib)) - - val ast = builder.closureAST - module.add(new CompilerInput(ast, ast.getInputId(), false)) - - for (export <- inputs.additionalExports) - module.add(toClosureInput(export)) - - // Compile the module - val closureExterns = - (ScalaJSExternsFile +: inputs.additionalExterns).map(toClosureSource) - - val options = closureOptions(outCfg) - val compiler = closureCompiler(logger) - - val result = GenIncOptimizer.logTime(logger, "Closure Compiler pass") { - compiler.compileModules( - closureExterns.asJava, List(module).asJava, options) - } - - GenIncOptimizer.logTime(logger, "Write Closure result") { - writeResult(result, compiler, outCfg.output) - } - } - - private def writeResult(result: Result, compiler: ClosureCompiler, - output: WritableVirtualJSFile): Unit = { - - val outputContent = if (result.errors.nonEmpty) "" - else "(function(){'use strict';" + compiler.toSource + "}).call(this);\n" - - val sourceMap = Option(compiler.getSourceMap()) - - // Write optimized code - val w = output.contentWriter - try { - w.write(outputContent) - if (sourceMap.isDefined) - w.write("//# sourceMappingURL=" + output.name + ".map\n") - } finally w.close() - - // Write source map (if available) - sourceMap.foreach { sm => - val w = output.sourceMapWriter - try sm.appendTo(w, output.name) - finally w.close() - } - } - - private def closureOptions(optConfig: OptimizerConfig, - noSourceMap: Boolean = false) = { - - val options = new ClosureOptions - options.prettyPrint = optConfig.prettyPrint - CompilationLevel.ADVANCED_OPTIMIZATIONS.setOptionsForCompilationLevel(options) - options.setLanguageIn(ClosureOptions.LanguageMode.ECMASCRIPT5) - options.setCheckGlobalThisLevel(CheckLevel.OFF) - - if (!noSourceMap && optConfig.wantSourceMap) { - options.setSourceMapOutputPath(optConfig.output.name + ".map") - options.setSourceMapDetailLevel(SourceMap.DetailLevel.ALL) - } - - options - } - - private def closureCompiler(logger: Logger) = { - val compiler = new ClosureCompiler - compiler.setErrorManager(new LoggerErrorManager(logger)) - compiler - } -} - -object ScalaJSClosureOptimizer { - /** Inputs of the Scala.js Closure optimizer. */ - final case class Inputs[T]( - /** Input to optimize (classpath or file-list) */ - input: T, - /** Additional externs files to be given to Closure. */ - additionalExterns: Seq[VirtualJSFile] = Nil, - /** Additional exports to be given to Closure. - * These files are just appended to the classpath, given to Closure, - * but not used in the Scala.js optimizer pass when direct optimizing - */ - additionalExports: Seq[VirtualJSFile] = Nil - ) - - /** Configuration the closure part of the optimizer needs. - * See [[OutputConfig]] for a description of the fields. - */ - trait OptimizerConfig { - val output: WritableVirtualJSFile - val cache: Option[WritableVirtualTextFile] - val wantSourceMap: Boolean - val prettyPrint: Boolean - val relativizeSourceMapBase: Option[URI] - } - - /** Configuration for the output of the Scala.js Closure optimizer */ - final case class OutputConfig( - /** Writer for the output */ - output: WritableVirtualJSFile, - /** Cache file */ - cache: Option[WritableVirtualTextFile] = None, - /** If true, performs expensive checks of the IR for the used parts. */ - checkIR: Boolean = false, - /** If true, the optimizer removes trees that have not been used in the - * last run from the cache. Otherwise, all trees that has been used once, - * are kept in memory. */ - unCache: Boolean = true, - /** If true, no optimizations are performed */ - disableOptimizer: Boolean = false, - /** If true, nothing is performed incrementally */ - batchMode: Boolean = false, - /** Ask to produce source map for the output */ - wantSourceMap: Boolean = false, - /** Pretty-print the output. */ - prettyPrint: Boolean = false, - /** Base path to relativize paths in the source map */ - relativizeSourceMapBase: Option[URI] = None - ) extends OptimizerConfig with ScalaJSOptimizer.OptimizerConfig - - /** Minimal set of externs to compile Scala.js-emitted code with Closure. */ - val ScalaJSExterns = """ - /** @constructor */ - function Object() {} - Object.protoype.toString = function() {}; - /** @constructor */ - function Array() {} - Array.prototype.length = 0; - /** @constructor */ - function Function() {} - Function.prototype.constructor = function() {}; - Function.prototype.call = function() {}; - Function.prototype.apply = function() {}; - var global = {}; - var __ScalaJSEnv = {}; - """ - - val ScalaJSExternsFile = new MemVirtualJSFile("ScalaJSExterns.js"). - withContent(ScalaJSExterns) - -} |