diff options
Diffstat (limited to 'examples/scala-js/sbt-plugin/src/main/scala/scala/scalajs/sbtplugin/ScalaJSPluginInternal.scala')
-rw-r--r-- | examples/scala-js/sbt-plugin/src/main/scala/scala/scalajs/sbtplugin/ScalaJSPluginInternal.scala | 598 |
1 files changed, 0 insertions, 598 deletions
diff --git a/examples/scala-js/sbt-plugin/src/main/scala/scala/scalajs/sbtplugin/ScalaJSPluginInternal.scala b/examples/scala-js/sbt-plugin/src/main/scala/scala/scalajs/sbtplugin/ScalaJSPluginInternal.scala deleted file mode 100644 index fe97f0b..0000000 --- a/examples/scala-js/sbt-plugin/src/main/scala/scala/scalajs/sbtplugin/ScalaJSPluginInternal.scala +++ /dev/null @@ -1,598 +0,0 @@ -package scala.scalajs.sbtplugin - -import sbt._ -import sbt.inc.{IncOptions, ClassfileManager} -import Keys._ - -import Implicits._ -import JSUtils._ - -import scala.scalajs.tools.sem.Semantics -import scala.scalajs.tools.io.{IO => toolsIO, _} -import scala.scalajs.tools.classpath._ -import scala.scalajs.tools.classpath.builder._ -import scala.scalajs.tools.jsdep._ -import scala.scalajs.tools.optimizer.{ - ScalaJSOptimizer, - ScalaJSClosureOptimizer, - IncOptimizer, - ParIncOptimizer -} -import scala.scalajs.tools.corelib.CoreJSLibs - -import scala.scalajs.tools.env._ -import scala.scalajs.sbtplugin.env.rhino.RhinoJSEnv -import scala.scalajs.sbtplugin.env.nodejs.NodeJSEnv -import scala.scalajs.sbtplugin.env.phantomjs.{PhantomJSEnv, PhantomJettyClassLoader} - -import scala.scalajs.ir.ScalaJSVersions - -import scala.scalajs.sbtplugin.testing.{TestFramework, JSClasspathLoader} - -import scala.util.Try - -import java.nio.charset.Charset -import java.net.URLClassLoader - -/** Contains settings used by ScalaJSPlugin that should not be automatically - * be in the *.sbt file's scope. - */ -object ScalaJSPluginInternal { - - import ScalaJSPlugin.autoImport._ - - /** Dummy setting to ensure we do not fork in Scala.js run & test. */ - val scalaJSEnsureUnforked = SettingKey[Boolean]("ensureUnforked", - "Scala.js internal: Fails if fork is true.", KeyRanks.Invisible) - - /** Dummy setting to persist Scala.js optimizer */ - val scalaJSOptimizer = SettingKey[ScalaJSOptimizer]("scalaJSOptimizer", - "Scala.js internal: Setting to persist the optimizer", KeyRanks.Invisible) - - /** Internal task to calculate whether a project requests the DOM - * (through jsDependencies or requiresDOM) */ - val scalaJSRequestsDOM = TaskKey[Boolean]("scalaJSRequestsDOM", - "Scala.js internal: Whether a project really wants the DOM. " + - "Calculated using requiresDOM and jsDependencies", KeyRanks.Invisible) - - /** Default post link environment */ - val scalaJSDefaultPostLinkJSEnv = TaskKey[JSEnv]("scalaJSDefaultPostLinkJSEnv", - "Scala.js internal: Default for postLinkJSEnv", KeyRanks.Invisible) - - /** Lookup key for CompleteClasspath in attribute maps */ - val scalaJSCompleteClasspath = - AttributeKey[CompleteClasspath]("scalaJSCompleteClasspath") - - /** Patches the IncOptions so that .sjsir files are pruned as needed. - * - * This complicated logic patches the ClassfileManager factory of the given - * IncOptions with one that is aware of .sjsir files emitted by the Scala.js - * compiler. This makes sure that, when a .class file must be deleted, the - * corresponding .sjsir file are also deleted. - */ - def scalaJSPatchIncOptions(incOptions: IncOptions): IncOptions = { - val inheritedNewClassfileManager = incOptions.newClassfileManager - val newClassfileManager = () => new ClassfileManager { - private[this] val inherited = inheritedNewClassfileManager() - - def delete(classes: Iterable[File]): Unit = { - inherited.delete(classes flatMap { classFile => - val scalaJSFiles = if (classFile.getPath endsWith ".class") { - val f = FileVirtualFile.withExtension(classFile, ".class", ".sjsir") - if (f.exists) List(f) - else Nil - } else Nil - classFile :: scalaJSFiles - }) - } - - def generated(classes: Iterable[File]): Unit = inherited.generated(classes) - def complete(success: Boolean): Unit = inherited.complete(success) - } - incOptions.copy(newClassfileManager = newClassfileManager) - } - - private def scalaJSOptimizerSetting(key: TaskKey[_]): Setting[_] = ( - scalaJSOptimizer in key := { - val semantics = (scalaJSSemantics in key).value - if ((scalaJSOptimizerOptions in key).value.parallel) - new ScalaJSOptimizer(semantics, new ParIncOptimizer(_)) - else - new ScalaJSOptimizer(semantics, new IncOptimizer(_)) - } - ) - - val scalaJSConfigSettings: Seq[Setting[_]] = Seq( - incOptions ~= scalaJSPatchIncOptions - ) ++ Seq( - - scalaJSPreLinkClasspath := { - val cp = fullClasspath.value - val pcp = PartialClasspathBuilder.build(Attributed.data(cp).toList) - val ccp = pcp.resolve(jsDependencyFilter.value) - - if (checkScalaJSSemantics.value) - ccp.checkCompliance(scalaJSSemantics.value) - - ccp - }, - - artifactPath in fastOptJS := - ((crossTarget in fastOptJS).value / - ((moduleName in fastOptJS).value + "-fastopt.js")), - - scalaJSOptimizerSetting(fastOptJS), - - fastOptJS := { - val s = streams.value - val output = (artifactPath in fastOptJS).value - val taskCache = - WritableFileVirtualTextFile(s.cacheDirectory / "fastopt-js") - - IO.createDirectory(output.getParentFile) - - val relSourceMapBase = - if ((relativeSourceMaps in fastOptJS).value) - Some(output.getParentFile.toURI()) - else None - - val opts = (scalaJSOptimizerOptions in fastOptJS).value - - import ScalaJSOptimizer._ - val outCP = (scalaJSOptimizer in fastOptJS).value.optimizeCP( - Inputs(input = (scalaJSPreLinkClasspath in fastOptJS).value), - OutputConfig( - output = WritableFileVirtualJSFile(output), - cache = Some(taskCache), - wantSourceMap = (emitSourceMaps in fastOptJS).value, - relativizeSourceMapBase = relSourceMapBase, - checkIR = opts.checkScalaJSIR, - disableOptimizer = opts.disableOptimizer, - batchMode = opts.batchMode), - s.log) - - Attributed.blank(output).put(scalaJSCompleteClasspath, outCP) - }, - fastOptJS <<= - fastOptJS.dependsOn(packageJSDependencies, packageScalaJSLauncher), - - artifactPath in fullOptJS := - ((crossTarget in fullOptJS).value / - ((moduleName in fullOptJS).value + "-opt.js")), - - scalaJSSemantics in fullOptJS := - (scalaJSSemantics in fastOptJS).value.optimized, - - scalaJSOptimizerSetting(fullOptJS), - - fullOptJS := { - val s = streams.value - val output = (artifactPath in fullOptJS).value - val taskCache = - WritableFileVirtualTextFile(s.cacheDirectory / "fullopt-js") - - IO.createDirectory(output.getParentFile) - - val relSourceMapBase = - if ((relativeSourceMaps in fullOptJS).value) - Some(output.getParentFile.toURI()) - else None - - val opts = (scalaJSOptimizerOptions in fullOptJS).value - - val semantics = (scalaJSSemantics in fullOptJS).value - - import ScalaJSClosureOptimizer._ - val outCP = new ScalaJSClosureOptimizer(semantics).optimizeCP( - (scalaJSOptimizer in fullOptJS).value, - Inputs(ScalaJSOptimizer.Inputs( - input = (scalaJSPreLinkClasspath in fullOptJS).value)), - OutputConfig( - output = WritableFileVirtualJSFile(output), - cache = Some(taskCache), - wantSourceMap = (emitSourceMaps in fullOptJS).value, - relativizeSourceMapBase = relSourceMapBase, - checkIR = opts.checkScalaJSIR, - disableOptimizer = opts.disableOptimizer, - batchMode = opts.batchMode, - prettyPrint = opts.prettyPrintFullOptJS), - s.log) - - Attributed.blank(output).put(scalaJSCompleteClasspath, outCP) - }, - - artifactPath in packageScalaJSLauncher := - ((crossTarget in packageScalaJSLauncher).value / - ((moduleName in packageScalaJSLauncher).value + "-launcher.js")), - - skip in packageScalaJSLauncher := !persistLauncher.value, - - packageScalaJSLauncher <<= Def.taskDyn { - if ((skip in packageScalaJSLauncher).value) - Def.task(Attributed.blank((artifactPath in packageScalaJSLauncher).value)) - else Def.task { - mainClass.value map { mainCl => - val file = (artifactPath in packageScalaJSLauncher).value - IO.write(file, launcherContent(mainCl), Charset.forName("UTF-8")) - - // Attach the name of the main class used, (ab?)using the name key - Attributed(file)(AttributeMap.empty.put(name.key, mainCl)) - } getOrElse { - sys.error("Cannot write launcher file, since there is no or multiple mainClasses") - } - } - }, - - artifactPath in packageJSDependencies := - ((crossTarget in packageJSDependencies).value / - ((moduleName in packageJSDependencies).value + "-jsdeps.js")), - - packageJSDependencies <<= Def.taskDyn { - if ((skip in packageJSDependencies).value) - Def.task((artifactPath in packageJSDependencies).value) - else Def.task { - val cp = scalaJSPreLinkClasspath.value - val output = (artifactPath in packageJSDependencies).value - val taskCache = WritableFileVirtualJSFile( - streams.value.cacheDirectory / "package-js-deps") - - IO.createDirectory(output.getParentFile) - - val outFile = WritableFileVirtualTextFile(output) - CacheUtils.cached(cp.version, outFile, Some(taskCache)) { - toolsIO.concatFiles(outFile, cp.jsLibs.map(_.lib)) - } - - output - } - }, - - jsDependencyManifest := { - val myModule = thisProject.value.id - val config = configuration.value.name - - // Collect all libraries - val jsDeps = jsDependencies.value.collect { - case dep: JSModuleID if dep.configurations.forall(_ == config) => - dep.jsDep - } - - val requiresDOM = jsDependencies.value.exists { - case RuntimeDOM(configurations) => - configurations.forall(_ == config) - case _ => false - } - - val compliantSemantics = scalaJSSemantics.value.compliants - - val manifest = new JSDependencyManifest(new Origin(myModule, config), - jsDeps.toList, requiresDOM, compliantSemantics) - - // Write dependency file to class directory - val targetDir = classDirectory.value - IO.createDirectory(targetDir) - - val file = targetDir / JSDependencyManifest.ManifestFileName - val vfile = WritableFileVirtualTextFile(file) - - // Prevent writing if unnecessary to not invalidate dependencies - val needWrite = !vfile.exists || { - Try { - val readManifest = JSDependencyManifest.read(vfile) - readManifest != manifest - } getOrElse true - } - - if (needWrite) - JSDependencyManifest.write(manifest, vfile) - - file - }, - - products <<= products.dependsOn(jsDependencyManifest), - - console <<= console.dependsOn(Def.task( - streams.value.log.warn("Scala REPL doesn't work with Scala.js. You " + - "are running a JVM REPL. JavaScript things won't work.") - )), - - // Give tasks ability to check we are not forking at build reading time - scalaJSEnsureUnforked := { - if (fork.value) - sys.error("Scala.js cannot be run in a forked JVM") - else - true - }, - - scalaJSRequestsDOM := - requiresDOM.?.value.getOrElse(scalaJSExecClasspath.value.requiresDOM), - - // Default jsEnv - jsEnv <<= Def.taskDyn { - scalaJSStage.value match { - case Stage.PreLink => - Def.task { - preLinkJSEnv.?.value.getOrElse { - new RhinoJSEnv(scalaJSSemantics.value, - withDOM = scalaJSRequestsDOM.value) - } - } - case Stage.FastOpt | Stage.FullOpt => - Def.task(scalaJSDefaultPostLinkJSEnv.value) - } - }, - - // Wire jsEnv and sources for other stages - scalaJSDefaultPostLinkJSEnv := postLinkJSEnv.?.value.getOrElse { - if (scalaJSRequestsDOM.value) - new PhantomJSEnv(jettyClassLoader = scalaJSPhantomJSClassLoader.value) - else - new NodeJSEnv - }, - - scalaJSExecClasspath <<= Def.taskDyn { - scalaJSStage.value match { - case Stage.PreLink => - Def.task { scalaJSPreLinkClasspath.value } - case Stage.FastOpt => - Def.task { fastOptJS.value.get(scalaJSCompleteClasspath).get } - case Stage.FullOpt => - Def.task { fullOptJS.value.get(scalaJSCompleteClasspath).get } - } - } - ) - - /** Run a class in a given environment using a given launcher */ - private def jsRun(env: JSEnv, cp: CompleteClasspath, mainCl: String, - launcher: VirtualJSFile, jsConsole: JSConsole, log: Logger) = { - - log.info("Running " + mainCl) - log.debug(s"with JSEnv of type ${env.getClass()}") - log.debug(s"with classpath of type ${cp.getClass}") - - // Actually run code - env.jsRunner(cp, launcher, log, jsConsole).run() - } - - private def launcherContent(mainCl: String) = { - // If we are running in Node.js, we need to bracket select on - // global rather than this - """((typeof global === "object" && global && - global["Object"] === Object) ? global : this)""" + - s"${dot2bracket(mainCl)}().main();\n" - } - - private def memLauncher(mainCl: String) = { - new MemVirtualJSFile("Generated launcher file") - .withContent(launcherContent(mainCl)) - } - - // These settings will be filtered by the stage dummy tasks - val scalaJSRunSettings = Seq( - mainClass in scalaJSLauncher := (mainClass in run).value, - scalaJSLauncher <<= Def.taskDyn { - if (persistLauncher.value) - Def.task(packageScalaJSLauncher.value.map(FileVirtualJSFile)) - else Def.task { - (mainClass in scalaJSLauncher).value map { mainClass => - val memLaunch = memLauncher(mainClass) - Attributed[VirtualJSFile](memLaunch)( - AttributeMap.empty.put(name.key, mainClass)) - } getOrElse { - sys.error("No main class detected.") - } - } - }, - - /* We do currently not discover objects containing a - * - * def main(args: Array[String]): Unit - * - * Support will be added again, as soon as we can run them - * reliably (e.g. without implicitly requiring that an exported - * - * def main(): Unit - * - * exists alongside. - */ - discoveredMainClasses := { - import xsbt.api.{Discovered, Discovery} - - val jsApp = "scala.scalajs.js.JSApp" - - def isJSApp(discovered: Discovered) = - discovered.isModule && discovered.baseClasses.contains(jsApp) - - Discovery(Set(jsApp), Set.empty)(Tests.allDefs(compile.value)) collect { - case (definition, discovered) if isJSApp(discovered) => - definition.name - } - }, - - run <<= Def.inputTask { - // use assert to prevent warning about pure expr in stat pos - assert(scalaJSEnsureUnforked.value) - - val launch = scalaJSLauncher.value - val className = launch.get(name.key).getOrElse("<unknown class>") - jsRun(jsEnv.value, scalaJSExecClasspath.value, className, - launch.data, scalaJSConsole.value, streams.value.log) - }, - - runMain <<= { - // Implicits for parsing - import sbinary.DefaultProtocol.StringFormat - import Cache.seqFormat - - val parser = Defaults.loadForParser(discoveredMainClasses)((s, names) => - Defaults.runMainParser(s, names getOrElse Nil)) - - Def.inputTask { - // use assert to prevent warning about pure expr in stat pos - assert(scalaJSEnsureUnforked.value) - - val mainCl = parser.parsed._1 - jsRun(jsEnv.value, scalaJSExecClasspath.value, mainCl, - memLauncher(mainCl), scalaJSConsole.value, streams.value.log) - } - } - ) - - val scalaJSCompileSettings = ( - scalaJSConfigSettings ++ - scalaJSRunSettings - ) - - val scalaJSTestFrameworkSettings = Seq( - // Copied from Defaults, but scoped. We need a JVM loader in - // loadedTestFrameworks to find out whether the framework exists. - testLoader in loadedTestFrameworks := { - TestFramework.createTestLoader( - Attributed.data(fullClasspath.value), - scalaInstance.value, - IO.createUniqueDirectory(taskTemporaryDirectory.value)) - }, - - loadedTestFrameworks := { - // use assert to prevent warning about pure expr in stat pos - assert(scalaJSEnsureUnforked.value) - - val loader = (testLoader in loadedTestFrameworks).value - val isTestFrameworkDefined = try { - Class.forName(scalaJSTestFramework.value, false, loader) - true - } catch { - case _: ClassNotFoundException => false - } - if (isTestFrameworkDefined) { - loadedTestFrameworks.value.updated( - sbt.TestFramework(classOf[TestFramework].getName), - new TestFramework( - environment = jsEnv.value, - jsConsole = scalaJSConsole.value, - testFramework = scalaJSTestFramework.value) - ) - } else { - loadedTestFrameworks.value - } - }, - - // Pseudo loader to pass classpath to test framework - testLoader := JSClasspathLoader(scalaJSExecClasspath.value) - ) - - val scalaJSTestBuildSettings = ( - scalaJSConfigSettings - ) ++ ( - Seq(fastOptJS, fullOptJS, packageScalaJSLauncher, - packageJSDependencies) map { packageJSTask => - moduleName in packageJSTask := moduleName.value + "-test" - } - ) - - val scalaJSTestSettings = ( - scalaJSTestBuildSettings ++ - scalaJSTestFrameworkSettings - ) - - val scalaJSDependenciesSettings = Seq( - // add all the webjars your jsDependencies depend upon - libraryDependencies ++= jsDependencies.value.collect { - case JarJSModuleID(module, _) => module - } - ) - - val scalaJSDefaultBuildConfigs = ( - inConfig(Compile)(scalaJSConfigSettings) ++ // build settings for Compile - inConfig(Test)(scalaJSTestBuildSettings) ++ - scalaJSDependenciesSettings - ) - - val scalaJSDefaultConfigs = ( - inConfig(Compile)(scalaJSCompileSettings) ++ - inConfig(Test)(scalaJSTestSettings) ++ - scalaJSDependenciesSettings - ) - - val phantomJSJettyModules = Seq( - "org.eclipse.jetty" % "jetty-websocket" % "8.1.16.v20140903", - "org.eclipse.jetty" % "jetty-server" % "8.1.16.v20140903" - ) - - val scalaJSProjectBaseSettings = Seq( - relativeSourceMaps := false, - persistLauncher := false, - - skip in packageJSDependencies := true, - - scalaJSTestFramework := "org.scalajs.jasminetest.JasmineTestFramework", - - emitSourceMaps := true, - - scalaJSOptimizerOptions := OptimizerOptions(), - - jsDependencies := Seq(), - jsDependencyFilter := identity, - - scalaJSSemantics := Semantics.Defaults, - checkScalaJSSemantics := true, - - scalaJSConsole := ConsoleJSConsole, - - clean <<= clean.dependsOn(Def.task { - // have clean reset incremental optimizer state - (scalaJSOptimizer in (Compile, fastOptJS)).value.clean() - (scalaJSOptimizer in (Test, fastOptJS)).value.clean() - }), - - /* Depend on jetty artifacts in dummy configuration to be able to inject - * them into the PhantomJS runner if necessary. - * See scalaJSPhantomJSClassLoader - */ - ivyConfigurations += config("phantom-js-jetty").hide, - libraryDependencies ++= phantomJSJettyModules.map(_ % "phantom-js-jetty"), - scalaJSPhantomJSClassLoader := { - val report = update.value - val jars = report.select(configurationFilter("phantom-js-jetty")) - - val jettyLoader = - new URLClassLoader(jars.map(_.toURI.toURL).toArray, null) - - new PhantomJettyClassLoader(jettyLoader, getClass.getClassLoader) - } - ) - - val scalaJSAbstractSettings: Seq[Setting[_]] = ( - scalaJSProjectBaseSettings ++ - scalaJSDefaultConfigs - ) - - val scalaJSAbstractBuildSettings: Seq[Setting[_]] = ( - scalaJSProjectBaseSettings ++ - scalaJSDefaultBuildConfigs - ) - - val scalaJSReleasesResolver = Resolver.url("scala-js-releases", - url("http://dl.bintray.com/content/scala-js/scala-js-releases"))( - Resolver.ivyStylePatterns) - val scalaJSSnapshotsResolver = Resolver.url("scala-js-snapshots", - url("http://repo.scala-js.org/repo/snapshots/"))( - Resolver.ivyStylePatterns) - - val scalaJSEcosystemSettings = Seq( - // the resolver to find the compiler and library (and others) - resolvers ++= Seq(scalaJSReleasesResolver, scalaJSSnapshotsResolver), - - // you will need the Scala.js compiler plugin - autoCompilerPlugins := true, - addCompilerPlugin( - "org.scala-lang.modules.scalajs" % "scalajs-compiler" % scalaJSVersion cross CrossVersion.full), - - // and of course the Scala.js library - libraryDependencies += "org.scala-lang.modules.scalajs" %% "scalajs-library" % scalaJSVersion, - - // and you will want to be cross-compiled on the Scala.js binary version - crossVersion := ScalaJSCrossVersion.binary - ) - -} |