summaryrefslogtreecommitdiff
path: root/scalajslib/src
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-01-24 22:05:33 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-01-25 07:08:54 -0800
commit11c194da920cd6a4196ddfbb875c0d1faa47fcff (patch)
tree324e4e4519ba4498ba0a8081c1256fb841603af5 /scalajslib/src
parentfdaf23824b4dd579daafb2de49123bcc5f2e4228 (diff)
downloadmill-11c194da920cd6a4196ddfbb875c0d1faa47fcff.tar.gz
mill-11c194da920cd6a4196ddfbb875c0d1faa47fcff.tar.bz2
mill-11c194da920cd6a4196ddfbb875c0d1faa47fcff.zip
Migrate `scalajslib` over to a `T.worker` setup similar to `scalalib`
Diffstat (limited to 'scalajslib/src')
-rw-r--r--scalajslib/src/mill/scalajslib/Lib.scala62
-rw-r--r--scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala62
-rw-r--r--scalajslib/src/mill/scalajslib/ScalaJSModule.scala74
3 files changed, 109 insertions, 89 deletions
diff --git a/scalajslib/src/mill/scalajslib/Lib.scala b/scalajslib/src/mill/scalajslib/Lib.scala
deleted file mode 100644
index 6a85cf0c..00000000
--- a/scalajslib/src/mill/scalajslib/Lib.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-package mill
-package scalajslib
-
-import java.io.File
-import java.net.URLClassLoader
-
-import ammonite.ops.{Path, mkdir, rm, _}
-import mill.eval.PathRef
-import mill.scalalib.Dep
-import mill.util.{Ctx, Loose}
-
-import scala.collection.breakOut
-import scala.language.reflectiveCalls
-
-private object LinkerBridge {
- @volatile var scalaInstanceCache = Option.empty[(Long, ScalaJSLinkerBridge)]
-}
-
-object Lib {
-
- def scalaJSLinkerIvyDep(scalaJSVersion: String): Dep =
- Dep("com.lihaoyi", s"mill-jsbridge_${scalaJSVersion.replace('.', '_')}", "0.1-SNAPSHOT")
-
- def scalaJSLinkerBridge(classPath: Loose.Agg[Path]): ScalaJSLinkerBridge = {
- val classloaderSig = classPath.map(p => p.toString().hashCode + p.mtime.toMillis).sum
- LinkerBridge.scalaInstanceCache match {
- case Some((`classloaderSig`, linker)) => linker
- case _ =>
- val cl = new URLClassLoader(classPath.map(_.toIO.toURI.toURL).toArray)
- val bridge = cl.loadClass("mill.scalajslib.bridge.ScalaJSLinkerBridge")
- .getDeclaredConstructor().newInstance().asInstanceOf[ {
- def link(sources: Array[File], libraries: Array[File], dest: File, main: String, fullOpt: Boolean): Unit
- }]
- val linker: ScalaJSLinkerBridge = (sources: Seq[File],
- libraries: Seq[File],
- dest: File,
- main: Option[String],
- mode: OptimizeMode) =>
- bridge.link(sources.toArray, libraries.toArray, dest, main.orNull, mode == FullOpt)
- LinkerBridge.scalaInstanceCache = Some((classloaderSig, linker))
- linker
- }
- }
-
- def link(main: Option[String],
- inputPaths: Seq[Path],
- libraries: Loose.Agg[Path],
- linker: ScalaJSLinkerBridge,
- mode: OptimizeMode)
- (implicit ctx: Ctx.DestCtx): PathRef = {
- val outputPath = ctx.dest.copy(segments = ctx.dest.segments.init :+ (ctx.dest.segments.last + ".js"))
- rm(outputPath)
- if (inputPaths.nonEmpty) {
- mkdir(outputPath / up)
- val inputFiles: Vector[File] = inputPaths.map(ls).flatMap(_.filter(_.ext == "sjsir")).map(_.toIO)(breakOut)
- val inputLibraries: Vector[File] = libraries.filter(_.ext == "jar").map(_.toIO).toVector
- linker.link(inputFiles, inputLibraries, outputPath.toIO, main, mode)
- }
- PathRef(outputPath)
- }
-
-}
diff --git a/scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala b/scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala
index 448cc16a..ae282152 100644
--- a/scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala
+++ b/scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala
@@ -1,12 +1,72 @@
package mill.scalajslib
import java.io.File
+import java.net.URLClassLoader
+
+import ammonite.ops.Path
+import mill.{Agg, T}
sealed trait OptimizeMode
object FastOpt extends OptimizeMode
object FullOpt extends OptimizeMode
+class ScalaJSLinkerWorker {
+ var scalaInstanceCache = Option.empty[(Long, ScalaJSLinkerBridge)]
+ def link(toolsClasspath: Agg[Path],
+ sources: Agg[Path],
+ libraries: Agg[Path],
+ dest: File,
+ main: Option[String],
+ fullOpt: Boolean): Unit = {
+
+ val classloaderSig = {
+ toolsClasspath.map(p => p.toString().hashCode + p.mtime.toMillis).sum
+ }
+
+ val bridge = scalaInstanceCache match{
+ case Some((sig, bridge)) if sig == classloaderSig => bridge
+ case _ =>
+ val outerClassLoader = getClass.getClassLoader
+ val cl = new URLClassLoader(toolsClasspath.map(_.toIO.toURI.toURL).toArray){
+ override def findClass(name: String) = {
+ if (name.startsWith("mill.scalajslib.ScalaJSLinkerBridge")){
+ outerClassLoader.loadClass(name)
+ }else{
+ super.findClass(name)
+ }
+ }
+ }
+ val bridge = cl
+ .loadClass("mill.scalajslib.bridge.ScalaJSLinkerBridge")
+ .getDeclaredConstructor()
+ .newInstance()
+ .asInstanceOf[ScalaJSLinkerBridge]
+ scalaInstanceCache = Some((classloaderSig, bridge))
+ bridge
+ }
+ bridge.link(
+ sources.items.map(_.toIO).toArray,
+ libraries.items.map(_.toIO).toArray,
+ dest,
+ main.orNull,
+ fullOpt
+ )
+ }
+
+}
+
trait ScalaJSLinkerBridge {
- def link(sources: Seq[File], libraries: Seq[File], dest: File, main: Option[String], mode: OptimizeMode): Unit
+ def link(sources: Array[File],
+ libraries: Array[File],
+ dest: File,
+ main: String,
+ fullOpt: Boolean): Unit
}
+
+object ScalaJSLinkerBridge extends mill.define.BaseModule(ammonite.ops.pwd){
+
+ def scalaJSLinkerBridge = T.worker{
+ new ScalaJSLinkerWorker()
+ }
+} \ No newline at end of file
diff --git a/scalajslib/src/mill/scalajslib/ScalaJSModule.scala b/scalajslib/src/mill/scalajslib/ScalaJSModule.scala
index 5c964fd6..0286d573 100644
--- a/scalajslib/src/mill/scalajslib/ScalaJSModule.scala
+++ b/scalajslib/src/mill/scalajslib/ScalaJSModule.scala
@@ -3,13 +3,17 @@ package scalajslib
import java.io.File
-import ammonite.ops.Path
+import mill.scalalib.DepSyntax
+import ammonite.ops.{Path, ls, mkdir, rm}
+import coursier.maven.MavenRepository
+import mill.eval.PathRef
import mill.eval.Result.Success
-import mill.scalajslib.Lib._
import mill.scalalib.Lib.resolveDependencies
-import mill.scalalib.{Dep, ScalaModule, PublishModule, TestModule}
+import mill.scalalib.{Dep, PublishModule, ScalaModule, TestModule}
import mill.util.Loose
+import scala.collection.breakOut
+
trait ScalaJSModule extends scalalib.ScalaModule { outer =>
def scalaJSVersion: T[String]
@@ -27,37 +31,55 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer =>
def scalaJSBridgeVersion = T{ scalaJSVersion().split('.').dropRight(1).mkString(".") }
- def scalaJSLinkerClasspath: T[Loose.Agg[PathRef]] = T{
+ def sjsLinkerBridgeClasspath = T {
val jsBridgeKey = "MILL_SCALAJS_BRIDGE_" + scalaJSBridgeVersion().replace('.', '_')
val jsBridgePath = sys.props(jsBridgeKey)
- if (jsBridgePath != null) {
- Success(
- Loose.Agg.from(
- jsBridgePath.split(File.pathSeparator).map(f => PathRef(Path(f), quick = true))
- )
- )
- }
- else {
- val dep = scalaJSLinkerIvyDep(scalaJSBridgeVersion())
- resolveDependencies(
- repositories,
- scalaVersion(),
- scalaBinaryVersion(),
- Seq(dep)
- )
- }
+ if (jsBridgePath != null) Success(
+ PathRef(Path(jsBridgePath), quick = true)
+ ) else resolveDependencies(
+ Seq(MavenRepository("https://repo1.maven.org/maven2")),
+ "2.12.4",
+ "2.12",
+ Seq(Dep(
+ "com.lihaoyi",
+ s"mill-jsbridge_${scalaJSBridgeVersion().replace('.', '_')}",
+ "0.1-SNAPSHOT"
+ ))
+ ).map(_.find(_.path.toString.contains("mill-jsbridge")).get)
}
- def fastOpt = T{
- val linker = scalaJSLinkerBridge(scalaJSLinkerClasspath().map(_.path))
- link(mainClass(), Seq(compile().classes.path), compileDepClasspath().map(_.path), linker, FastOpt)
+
+ def scalaJSLinkerClasspath: T[Loose.Agg[PathRef]] = T{
+ resolveDependencies(
+ repositories,
+ "2.12.4",
+ "2.12",
+ Seq(ivy"org.scala-js::scalajs-tools:${scalaJSVersion()}")
+ )
}
- def fullOpt = T{
- val linker = scalaJSLinkerBridge(scalaJSLinkerClasspath().map(_.path))
- link(mainClass(), Seq(compile().classes.path), compileDepClasspath().map(_.path), linker, FullOpt)
+ def genericOpt(mode: OptimizeMode) = T.task{
+ val outputPath = T.ctx().dest / "out.js"
+
+ mkdir(T.ctx().dest)
+ rm(outputPath)
+ val inputFiles = Agg.from(ls(compile().classes.path).filter(_.ext == "sjsir"))
+ val inputLibraries = compileDepClasspath().map(_.path).filter(_.ext == "jar")
+ mill.scalajslib.ScalaJSLinkerBridge.scalaJSLinkerBridge().link(
+ (Agg(sjsLinkerBridgeClasspath()) ++ scalaJSLinkerClasspath()).map(_.path),
+ inputFiles,
+ inputLibraries,
+ outputPath.toIO,
+ mainClass(),
+ mode == FullOpt
+ )
+ PathRef(outputPath)
}
+ def fastOpt = T{ genericOpt(FastOpt)() }
+
+ def fullOpt = T{ genericOpt(FullOpt)() }
+
override def scalacPluginIvyDeps = T{ Loose.Agg(Dep.Point("org.scala-js", "scalajs-compiler", scalaJSVersion())) }
override def ivyDeps = T{ Loose.Agg(Dep("org.scala-js", "scalajs-library", scalaJSVersion())) }