summaryrefslogtreecommitdiff
path: root/cli/src/main/scala/scala/scalajs/cli/Scalajsp.scala
diff options
context:
space:
mode:
Diffstat (limited to 'cli/src/main/scala/scala/scalajs/cli/Scalajsp.scala')
-rw-r--r--cli/src/main/scala/scala/scalajs/cli/Scalajsp.scala158
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)
+ }
+
+}