diff options
Diffstat (limited to 'examples/scala-js/cli')
8 files changed, 402 insertions, 0 deletions
diff --git a/examples/scala-js/cli/src/main/resources/scalajsc b/examples/scala-js/cli/src/main/resources/scalajsc new file mode 100755 index 0000000..7fd1100 --- /dev/null +++ b/examples/scala-js/cli/src/main/resources/scalajsc @@ -0,0 +1,16 @@ +#! /bin/sh + +SCALA_BIN_VER="@SCALA_BIN_VER@" +SCALAJS_VER="@SCALAJS_VER@" +SCALA_VER=$(scalac -version 2>&1 | grep -o '[0-9]\.[0-9][0-9]\.[0-9]') + +if [ "$(echo $SCALA_VER | cut -b 1-4)" != "$SCALA_BIN_VER" ]; then + echo "This bundle of Scala.js CLI is for $SCALA_BIN_VER. Your scala version is $SCALA_VER!" >&2 + exit 1 +fi + +BASE="$(dirname $0)/.." +PLUGIN="$BASE/lib/scalajs-compiler_$SCALA_VER-$SCALAJS_VER.jar" +JSLIB="$BASE/lib/scalajs-library_$SCALA_BIN_VER-$SCALAJS_VER.jar" + +scalac -classpath "$JSLIB" "-Xplugin:$PLUGIN" "$@" diff --git a/examples/scala-js/cli/src/main/resources/scalajsc.bat b/examples/scala-js/cli/src/main/resources/scalajsc.bat new file mode 100644 index 0000000..767c5df --- /dev/null +++ b/examples/scala-js/cli/src/main/resources/scalajsc.bat @@ -0,0 +1,14 @@ +@ECHO OFF +set SCALA_BIN_VER=@SCALA_BIN_VER@ +set SCALAJS_VER=@SCALAJS_VER@ + +for /F "tokens=5" %%i in (' scala -version 2^>^&1 1^>nul ') do set SCALA_VER=%%i + +if NOT "%SCALA_VER:~0,4%" == "%SCALA_BIN_VER%" ( + echo "This bundle of Scala.js CLI is for %SCALA_BIN_VER%. Your scala version is %SCALA_VER%!" 1>&2 +) else ( + set PLUGIN=%~dp0\..\lib\scalajs-compiler_%SCALA_VER%-%SCALAJS_VER%.jar + set JSLIB=%~dp0\..\lib\scalajs-library_%SCALA_BIN_VER%-%SCALAJS_VER%.jar + + scalac -classpath "%JSLIB%" "-Xplugin:%PLUGIN%" %* +) diff --git a/examples/scala-js/cli/src/main/resources/scalajsld b/examples/scala-js/cli/src/main/resources/scalajsld new file mode 100755 index 0000000..7732e2a --- /dev/null +++ b/examples/scala-js/cli/src/main/resources/scalajsld @@ -0,0 +1,10 @@ +#! /bin/sh + +SCALA_BIN_VER="@SCALA_BIN_VER@" +SCALAJS_VER="@SCALAJS_VER@" + +BASE="$(dirname $0)/.." +CLILIB="$BASE/lib/scalajs-cli-assembly_$SCALA_BIN_VER-$SCALAJS_VER.jar" +JSLIB="$BASE/lib/scalajs-library_$SCALA_BIN_VER-$SCALAJS_VER.jar" + +scala -classpath "$CLILIB" scala.scalajs.cli.Scalajsld --stdlib "$JSLIB" "$@" diff --git a/examples/scala-js/cli/src/main/resources/scalajsld.bat b/examples/scala-js/cli/src/main/resources/scalajsld.bat new file mode 100644 index 0000000..e915237 --- /dev/null +++ b/examples/scala-js/cli/src/main/resources/scalajsld.bat @@ -0,0 +1,8 @@ +@ECHO OFF +set SCALA_BIN_VER=@SCALA_BIN_VER@ +set SCALAJS_VER=@SCALAJS_VER@ + +set CLILIB="%~dp0\..\lib\scalajs-cli-assembly_%SCALA_BIN_VER%-%SCALAJS_VER%.jar" +set JSLIB="%~dp0\..\lib\scalajs-library_%SCALA_BIN_VER%-%SCALAJS_VER%.jar" + +scala -classpath %CLILIB% scala.scalajs.cli.Scalajsld --stdlib %JSLIB% %* diff --git a/examples/scala-js/cli/src/main/resources/scalajsp b/examples/scala-js/cli/src/main/resources/scalajsp new file mode 100755 index 0000000..e7a6e58 --- /dev/null +++ b/examples/scala-js/cli/src/main/resources/scalajsp @@ -0,0 +1,9 @@ +#! /bin/sh + +SCALA_BIN_VER="@SCALA_BIN_VER@" +SCALAJS_VER="@SCALAJS_VER@" + +BASE="$(dirname $0)/.." +CLILIB="$BASE/lib/scalajs-cli-assembly_$SCALA_BIN_VER-$SCALAJS_VER.jar" + +scala -classpath "$CLILIB" scala.scalajs.cli.Scalajsp "$@" diff --git a/examples/scala-js/cli/src/main/resources/scalajsp.bat b/examples/scala-js/cli/src/main/resources/scalajsp.bat new file mode 100644 index 0000000..dd9745c --- /dev/null +++ b/examples/scala-js/cli/src/main/resources/scalajsp.bat @@ -0,0 +1,7 @@ +@ECHO OFF +set SCALA_BIN_VER=@SCALA_BIN_VER@ +set SCALAJS_VER=@SCALAJS_VER@ + +set CLILIB="%~dp0\..\lib\scalajs-cli-assembly_%SCALA_BIN_VER%-%SCALAJS_VER%.jar" + +scala -classpath %CLILIB% scala.scalajs.cli.Scalajsp %* diff --git a/examples/scala-js/cli/src/main/scala/scala/scalajs/cli/Scalajsld.scala b/examples/scala-js/cli/src/main/scala/scala/scalajs/cli/Scalajsld.scala new file mode 100644 index 0000000..55e61af --- /dev/null +++ b/examples/scala-js/cli/src/main/scala/scala/scalajs/cli/Scalajsld.scala @@ -0,0 +1,180 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js CLI ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package scala.scalajs.cli + +import scala.scalajs.ir.ScalaJSVersions + +import scala.scalajs.tools.sem._ +import scala.scalajs.tools.io._ +import scala.scalajs.tools.logging._ +import scala.scalajs.tools.classpath._ +import scala.scalajs.tools.classpath.builder._ + +import CheckedBehavior.Compliant + +import scala.scalajs.tools.optimizer.{ + ScalaJSOptimizer, + ScalaJSClosureOptimizer, + ParIncOptimizer +} + +import scala.collection.immutable.Seq + +import java.io.File +import java.net.URI + +object Scalajsld { + + case class Options( + cp: Seq[File] = Seq.empty, + output: File = null, + jsoutput: Option[File] = None, + semantics: Semantics = Semantics.Defaults, + noOpt: Boolean = false, + fullOpt: Boolean = false, + prettyPrint: Boolean = false, + sourceMap: Boolean = false, + relativizeSourceMap: Option[URI] = None, + checkIR: Boolean = false, + stdLib: Option[File] = None, + logLevel: Level = Level.Info) + + def main(args: Array[String]): Unit = { + val parser = new scopt.OptionParser[Options]("scalajsld") { + head("scalajsld", ScalaJSVersions.current) + arg[File]("<value> ...") + .unbounded() + .action { (x, c) => c.copy(cp = c.cp :+ x) } + .text("Entries of Scala.js classpath to link") + opt[File]('o', "output") + .valueName("<file>") + .required() + .action { (x, c) => c.copy(output = x) } + .text("Output file of linker (required)") + opt[File]("jsoutput") + .valueName("<file>") + .abbr("jo") + .action { (x, c) => c.copy(jsoutput = Some(x)) } + .text("Concatenate all JavaScript libary dependencies to this file") + opt[Unit]('f', "fastOpt") + .action { (_, c) => c.copy(noOpt = false, fullOpt = false) } + .text("Optimize code (this is the default)") + opt[Unit]('n', "noOpt") + .action { (_, c) => c.copy(noOpt = true, fullOpt = false) } + .text("Don't optimize code") + opt[Unit]('u', "fullOpt") + .action { (_, c) => c.copy(noOpt = false, fullOpt = true) } + .text("Fully optimize code (uses Google Closure Compiler)") + opt[Unit]('p', "prettyPrint") + .action { (_, c) => c.copy(prettyPrint = true) } + .text("Pretty print full opted code (meaningful with -u)") + opt[Unit]('s', "sourceMap") + .action { (_, c) => c.copy(sourceMap = true) } + .text("Produce a source map for the produced code") + opt[Unit]("compliantAsInstanceOfs") + .action { (_, c) => c.copy(semantics = + c.semantics.withAsInstanceOfs(Compliant)) + } + .text("Use compliant asInstanceOfs") + opt[Unit]('c', "checkIR") + .action { (_, c) => c.copy(checkIR = true) } + .text("Check IR before optimizing") + opt[File]('r', "relativizeSourceMap") + .valueName("<path>") + .action { (x, c) => c.copy(relativizeSourceMap = Some(x.toURI)) } + .text("Relativize source map with respect to given path (meaningful with -s)") + opt[Unit]("noStdlib") + .action { (_, c) => c.copy(stdLib = None) } + .text("Don't automatcially include Scala.js standard library") + opt[File]("stdlib") + .valueName("<scala.js stdlib jar>") + .hidden() + .action { (x, c) => c.copy(stdLib = Some(x)) } + .text("Location of Scala.js standard libarary. This is set by the " + + "runner script and automatically prepended to the classpath. " + + "Use -n to not include it.") + opt[Unit]('d', "debug") + .action { (_, c) => c.copy(logLevel = Level.Debug) } + .text("Debug mode: Show full log") + opt[Unit]('q', "quiet") + .action { (_, c) => c.copy(logLevel = Level.Warn) } + .text("Only show warnings & errors") + opt[Unit]("really-quiet") + .abbr("qq") + .action { (_, c) => c.copy(logLevel = Level.Error) } + .text("Only show errors") + version("version") + .abbr("v") + .text("Show scalajsld version") + help("help") + .abbr("h") + .text("prints this usage text") + + override def showUsageOnError = true + } + + for (options <- parser.parse(args, Options())) { + val cpFiles = options.stdLib.toList ++ options.cp + // Load and resolve classpath + val cp = PartialClasspathBuilder.build(cpFiles).resolve() + + // Write JS dependencies if requested + for (jsout <- options.jsoutput) + IO.concatFiles(WritableFileVirtualJSFile(jsout), cp.jsLibs.map(_.lib)) + + // Link Scala.js code + val outFile = WritableFileVirtualJSFile(options.output) + if (options.fullOpt) + fullOpt(cp, outFile, options) + else + fastOpt(cp, outFile, options) + } + } + + private def fullOpt(cp: IRClasspath, + output: WritableVirtualJSFile, options: Options) = { + import ScalaJSClosureOptimizer._ + + val semantics = options.semantics.optimized + + new ScalaJSClosureOptimizer(semantics).optimizeCP( + newScalaJSOptimizer(semantics), + Inputs(ScalaJSOptimizer.Inputs(cp)), + OutputConfig( + output = output, + wantSourceMap = options.sourceMap, + relativizeSourceMapBase = options.relativizeSourceMap, + checkIR = options.checkIR, + prettyPrint = options.prettyPrint), + newLogger(options)) + } + + private def fastOpt(cp: IRClasspath, + output: WritableVirtualJSFile, options: Options) = { + import ScalaJSOptimizer._ + + newScalaJSOptimizer(options.semantics).optimizeCP( + Inputs(cp), + OutputConfig( + output = output, + wantSourceMap = options.sourceMap, + checkIR = options.checkIR, + disableOptimizer = options.noOpt, + relativizeSourceMapBase = options.relativizeSourceMap), + newLogger(options)) + } + + private def newLogger(options: Options) = + new ScalaConsoleLogger(options.logLevel) + + private def newScalaJSOptimizer(semantics: Semantics) = + new ScalaJSOptimizer(semantics, new ParIncOptimizer(_)) + +} diff --git a/examples/scala-js/cli/src/main/scala/scala/scalajs/cli/Scalajsp.scala b/examples/scala-js/cli/src/main/scala/scala/scalajs/cli/Scalajsp.scala new file mode 100644 index 0000000..0d64b93 --- /dev/null +++ b/examples/scala-js/cli/src/main/scala/scala/scalajs/cli/Scalajsp.scala @@ -0,0 +1,158 @@ +/* __ *\ +** ________ ___ / / ___ __ ____ Scala.js CLI ** +** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** +** /____/\___/_/ |_/____/_/ | |__/ /____/ ** +** |/____/ ** +\* */ + + +package scala.scalajs.cli + +import scala.scalajs.ir +import ir.ScalaJSVersions +import ir.Trees.{Tree, ClassDef} +import ir.Printers.{InfoPrinter, IRTreePrinter} + +import scala.scalajs.tools.sem.Semantics +import scala.scalajs.tools.javascript +import javascript.ScalaJSClassEmitter +import javascript.Printers.JSTreePrinter + +import scala.scalajs.tools.io._ +import scala.collection.immutable.Seq + +import java.io.{Console => _, _} +import java.util.zip.{ZipFile, ZipEntry} + +object Scalajsp { + + case class Options( + infos: Boolean = false, + desugar: Boolean = false, + showReflProxy: Boolean = false, + jar: Option[File] = None, + fileNames: Seq[String] = Seq.empty) + + def main(args: Array[String]): Unit = { + val parser = new scopt.OptionParser[Options]("scalajsp") { + head("scalajsp", ScalaJSVersions.current) + arg[String]("<file> ...") + .unbounded() + .action { (x, c) => c.copy(fileNames = c.fileNames :+ x) } + .text("*.sjsir file to display content of") + opt[File]('j', "jar") + .valueName("<jar>") + .action { (x, c) => c.copy(jar = Some(x)) } + .text("Read *.sjsir file(s) from the given JAR.") + opt[Unit]('d', "desugar") + .action { (_, c) => c.copy(desugar = true) } + .text("Desugar JS trees. This yields runnable JavaScript") + opt[Unit]('i', "infos") + .action { (_, c) => c.copy(infos = true) } + .text("Show DCE infos instead of trees") + opt[Unit]('p', "reflProxies") + .action { (_, c) => c.copy(showReflProxy = true) } + .text("Show reflective call proxies") + opt[Unit]('s', "supported") + .action { (_,_) => printSupported(); sys.exit() } + .text("Show supported Scala.js IR versions") + version("version") + .abbr("v") + .text("Show scalajsp version") + help("help") + .abbr("h") + .text("prints this usage text") + + override def showUsageOnError = true + } + + for { + options <- parser.parse(args, Options()) + fileName <- options.fileNames + } { + val vfile = options.jar map { jar => + readFromJar(jar, fileName) + } getOrElse { + readFromFile(fileName) + } + + displayFileContent(vfile, options) + } + } + + def printSupported(): Unit = { + import ScalaJSVersions._ + println(s"Emitted Scala.js IR version is: $binaryEmitted") + println("Supported Scala.js IR versions are") + binarySupported.foreach(v => println(s"* $v")) + } + + def displayFileContent(vfile: VirtualScalaJSIRFile, opts: Options): Unit = { + if (opts.infos) + new InfoPrinter(stdout).printClassInfo(vfile.info) + else { + val outTree = { + if (opts.showReflProxy) vfile.tree + else filterOutReflProxies(vfile.tree) + } + + if (opts.desugar) + new JSTreePrinter(stdout).printTopLevelTree( + new ScalaJSClassEmitter(Semantics.Defaults).genClassDef(outTree)) + else + new IRTreePrinter(stdout).printTopLevelTree(outTree) + } + + stdout.flush() + } + + private def fail(msg: String) = { + Console.err.println(msg) + sys.exit(1) + } + + private def readFromFile(fileName: String) = { + val file = new File(fileName) + + if (!file.exists) + fail(s"No such file: $fileName") + else if (!file.canRead) + fail(s"Unable to read file: $fileName") + else + FileVirtualScalaJSIRFile(file) + } + + private def readFromJar(jar: File, name: String) = { + val jarFile = + try { new ZipFile(jar) } + catch { case _: FileNotFoundException => fail(s"No such JAR: $jar") } + try { + val entry = jarFile.getEntry(name) + if (entry == null) + fail(s"No such file in jar: $name") + else { + val name = jarFile.getName + "#" + entry.getName + val content = + IO.readInputStreamToByteArray(jarFile.getInputStream(entry)) + new MemVirtualSerializedScalaJSIRFile(name).withContent(content) + } + } finally { + jarFile.close() + } + } + + private val stdout = + new BufferedWriter(new OutputStreamWriter(Console.out, "UTF-8")) + + private def filterOutReflProxies(tree: ClassDef): ClassDef = { + import ir.Trees._ + import ir.Definitions.isReflProxyName + val newDefs = tree.defs.filter { + case MethodDef(Ident(name, _), _, _, _) => !isReflProxyName(name) + case _ => true + } + tree.copy(defs = newDefs)(tree.pos) + } + +} |