diff options
Diffstat (limited to 'cli/src/main/scala/scala/scalajs/cli/Scalajsp.scala')
-rw-r--r-- | cli/src/main/scala/scala/scalajs/cli/Scalajsp.scala | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/cli/src/main/scala/scala/scalajs/cli/Scalajsp.scala b/cli/src/main/scala/scala/scalajs/cli/Scalajsp.scala new file mode 100644 index 0000000..0d64b93 --- /dev/null +++ b/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) + } + +} |