diff options
Diffstat (limited to 'examples/scala-js/compiler/src/main/scala/scala/scalajs/compiler/ScalaJSPlugin.scala')
-rw-r--r-- | examples/scala-js/compiler/src/main/scala/scala/scalajs/compiler/ScalaJSPlugin.scala | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/examples/scala-js/compiler/src/main/scala/scala/scalajs/compiler/ScalaJSPlugin.scala b/examples/scala-js/compiler/src/main/scala/scala/scalajs/compiler/ScalaJSPlugin.scala new file mode 100644 index 0000000..c3916ab --- /dev/null +++ b/examples/scala-js/compiler/src/main/scala/scala/scalajs/compiler/ScalaJSPlugin.scala @@ -0,0 +1,143 @@ +/* Scala.js compiler + * Copyright 2013 LAMP/EPFL + * @author Sébastien Doeraene + */ + +package scala.scalajs.compiler + +import scala.tools.nsc._ +import scala.tools.nsc.plugins.{ + Plugin => NscPlugin, PluginComponent => NscPluginComponent +} +import scala.collection.{ mutable, immutable } + +import java.net.{ URI, URISyntaxException } + +import scala.scalajs.ir.Trees + +/** Main entry point for the Scala.js compiler plugin + * + * @author Sébastien Doeraene + */ +class ScalaJSPlugin(val global: Global) extends NscPlugin { + import global._ + + val name = "scalajs" + val description = "Compile to JavaScript" + val components = { + if (global.forScaladoc) + List[NscPluginComponent](PrepInteropComponent) + else + List[NscPluginComponent](PrepInteropComponent, GenCodeComponent) + } + + /** Called when the JS ASTs are generated. Override for testing */ + def generatedJSAST(clDefs: List[Trees.Tree]): Unit = {} + + /** Addons for JavaScript platform */ + object jsAddons extends { + val global: ScalaJSPlugin.this.global.type = ScalaJSPlugin.this.global + } with JSGlobalAddons with Compat210Component + + object scalaJSOpts extends ScalaJSOptions { + import ScalaJSOptions.URIMap + var fixClassOf: Boolean = false + lazy val sourceURIMaps: List[URIMap] = { + if (_sourceURIMaps.nonEmpty) + _sourceURIMaps.reverse + else + relSourceMap.toList.map(URIMap(_, absSourceMap)) + } + var _sourceURIMaps: List[URIMap] = Nil + var relSourceMap: Option[URI] = None + var absSourceMap: Option[URI] = None + } + + object PrepInteropComponent extends { + val global: ScalaJSPlugin.this.global.type = ScalaJSPlugin.this.global + val jsAddons: ScalaJSPlugin.this.jsAddons.type = ScalaJSPlugin.this.jsAddons + val scalaJSOpts = ScalaJSPlugin.this.scalaJSOpts + override val runsAfter = List("typer") + override val runsBefore = List("pickle") + } with PrepJSInterop + + object GenCodeComponent extends { + val global: ScalaJSPlugin.this.global.type = ScalaJSPlugin.this.global + val jsAddons: ScalaJSPlugin.this.jsAddons.type = ScalaJSPlugin.this.jsAddons + val scalaJSOpts = ScalaJSPlugin.this.scalaJSOpts + override val runsAfter = List("mixin") + override val runsBefore = List("delambdafy", "cleanup", "terminal") + } with GenJSCode { + def generatedJSAST(clDefs: List[Trees.Tree]) = + ScalaJSPlugin.this.generatedJSAST(clDefs) + } + + override def processOptions(options: List[String], + error: String => Unit): Unit = { + import ScalaJSOptions.URIMap + import scalaJSOpts._ + + for (option <- options) { + if (option == "fixClassOf") { + fixClassOf = true + + } else if (option.startsWith("mapSourceURI:")) { + val uris = option.stripPrefix("mapSourceURI:").split("->") + + if (uris.length != 1 && uris.length != 2) { + error("relocateSourceMap needs one or two URIs as argument.") + } else { + try { + val from = new URI(uris.head) + val to = uris.lift(1).map(str => new URI(str)) + _sourceURIMaps ::= URIMap(from, to) + } catch { + case e: URISyntaxException => + error(s"${e.getInput} is not a valid URI") + } + } + + // The following options are deprecated (how do we show this to the user?) + } else if (option.startsWith("relSourceMap:")) { + val uriStr = option.stripPrefix("relSourceMap:") + try { relSourceMap = Some(new URI(uriStr)) } + catch { + case e: URISyntaxException => error(s"$uriStr is not a valid URI") + } + } else if (option.startsWith("absSourceMap:")) { + val uriStr = option.stripPrefix("absSourceMap:") + try { absSourceMap = Some(new URI(uriStr)) } + catch { + case e: URISyntaxException => error(s"$uriStr is not a valid URI") + } + } else { + error("Option not understood: " + option) + } + } + + // Verify constraints + if (_sourceURIMaps.nonEmpty && relSourceMap.isDefined) + error("You may not use mapSourceURI and relSourceMap together. " + + "Use another mapSourceURI option without second URI.") + else if (_sourceURIMaps.nonEmpty && absSourceMap.isDefined) + error("You may not use mapSourceURI and absSourceMap together. " + + "Use another mapSourceURI option.") + else if (absSourceMap.isDefined && relSourceMap.isEmpty) + error("absSourceMap requires the use of relSourceMap") + } + + override val optionsHelp: Option[String] = Some(s""" + | -P:$name:mapSourceURI:FROM_URI[->TO_URI] + | change the location the source URIs in the emitted IR point to + | - strips away the prefix FROM_URI (if it matches) + | - optionally prefixes the TO_URI, where stripping has been performed + | - any number of occurences are allowed. Processing is done on a first match basis. + | -P:$name:fixClassOf repair calls to Predef.classOf that reach ScalaJS + | WARNING: This is a tremendous hack! Expect ugly errors if you use this option. + |Deprecated options + | -P:$name:relSourceMap:<URI> relativize emitted source maps with <URI> + | -P:$name:absSourceMap:<URI> absolutize emitted source maps with <URI> + | This option requires the use of relSourceMap + """.stripMargin) + +} |