Skip to content

Commit

Permalink
Support ESFeatures in Scala.js (#1671)
Browse files Browse the repository at this point in the history
* Support ESFeatures in Scala.js

* Support older versions of ScalaJS

* Fix checkDeprecations task

* Fix JS tests

* Fix JS test to use correct version

* Use ctx.enclosing to check for overrides

* Run Scalafmt and fix test

* Do not fail if `useECMAScript2015` is deprecated

Pull request: #1671
  • Loading branch information
lolgab authored Jan 14, 2022
1 parent f0358b9 commit 9c818ae
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 114 deletions.
43 changes: 40 additions & 3 deletions scalajslib/api/src/ScalaJSWorkerApi.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package mill.scalajslib.api

import java.io.File
import mill.api.Result
import upickle.default.{ReadWriter => RW, macroRW}

trait ScalaJSWorkerApi {
def link(
sources: Array[File],
Expand All @@ -10,7 +13,7 @@ trait ScalaJSWorkerApi {
testBridgeInit: Boolean,
fullOpt: Boolean,
moduleKind: ModuleKind,
useECMAScript2015: Boolean
esFeatures: ESFeatures
): Result[File]

def run(config: JsEnvConfig, linkedFile: File): Unit
Expand All @@ -36,10 +39,44 @@ object ModuleKind {
object ESModule extends ModuleKind
}

sealed trait ESVersion
object ESVersion {
implicit val rw: RW[ESVersion] = macroRW[ESVersion]
object ES2015 extends ESVersion
object ES2016 extends ESVersion
object ES2017 extends ESVersion
object ES2018 extends ESVersion
object ES2019 extends ESVersion
object ES2020 extends ESVersion
object ES2021 extends ESVersion
object ES5_1 extends ESVersion
}

case class ESFeatures private (
allowBigIntsForLongs: Boolean,
avoidClasses: Boolean,
avoidLetsAndConsts: Boolean,
esVersion: ESVersion
) {
def withAllowBigIntsForLongs(allowBigIntsForLongs: Boolean): ESFeatures =
copy(allowBigIntsForLongs = allowBigIntsForLongs)
def withAvoidClasses(avoidClasses: Boolean): ESFeatures = copy(avoidClasses = avoidClasses)
def withAvoidLetsAndConsts(avoidLetsAndConsts: Boolean): ESFeatures =
copy(avoidLetsAndConsts = avoidLetsAndConsts)
def withESVersion(esVersion: ESVersion): ESFeatures = copy(esVersion = esVersion)
}
object ESFeatures {
val Defaults: ESFeatures = ESFeatures(
allowBigIntsForLongs = false,
avoidClasses = true,
avoidLetsAndConsts = true,
esVersion = ESVersion.ES2015
)
implicit val rw: RW[ESFeatures] = macroRW[ESFeatures]
}

sealed trait JsEnvConfig
object JsEnvConfig {

import upickle.default.{ReadWriter => RW, macroRW}
implicit def rwNodeJs: RW[NodeJs] = macroRW
implicit def rwJsDom: RW[JsDom] = macroRW
implicit def rwPhantom: RW[Phantom] = macroRW
Expand Down
21 changes: 15 additions & 6 deletions scalajslib/src/ScalaJSModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer =>
testBridgeInit = false,
mode = FastOpt,
moduleKind = moduleKind(),
useECMAScript2015 = useECMAScript2015()
esFeatures = esFeatures()
)
}

Expand All @@ -96,7 +96,7 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer =>
testBridgeInit = false,
mode = FullOpt,
moduleKind = moduleKind(),
useECMAScript2015 = useECMAScript2015()
esFeatures = esFeatures()
)
}

Expand Down Expand Up @@ -132,7 +132,7 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer =>
testBridgeInit: Boolean,
mode: OptimizeMode,
moduleKind: ModuleKind,
useECMAScript2015: Boolean
esFeatures: ESFeatures
)(implicit ctx: Ctx): Result[PathRef] = {
val outputPath = ctx.dest / "out.js"

Expand All @@ -154,7 +154,7 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer =>
testBridgeInit,
mode == FullOpt,
moduleKind,
useECMAScript2015
esFeatures
).map(PathRef(_))
}

Expand Down Expand Up @@ -197,10 +197,19 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer =>

def moduleKind: T[ModuleKind] = T { ModuleKind.NoModule }

def useECMAScript2015: T[Boolean] = T {
@deprecated("Use esFeatures().esVersion instead", since = "mill after 0.10.0-M5")
def useECMAScript2015: T[Boolean] = T {
!scalaJSVersion().startsWith("0.")
}

def esFeatures: T[ESFeatures] = T {
if (useECMAScript2015.ctx.enclosing != s"${classOf[ScalaJSModule].getName}#useECMAScript2015") {
T.log.error("Overriding `useECMAScript2015` is deprecated. Override `esFeatures` instead")
}
if (useECMAScript2015()) ESFeatures.Defaults
else ESFeatures.Defaults.withESVersion(ESVersion.ES5_1)
}

@internal
override def bspBuildTargetData: Task[Option[(String, AnyRef)]] = T.task {
Some((
Expand Down Expand Up @@ -239,7 +248,7 @@ trait TestScalaJSModule extends ScalaJSModule with TestModule {
testBridgeInit = true,
FastOpt,
moduleKind(),
useECMAScript2015()
esFeatures()
)
}

Expand Down
4 changes: 2 additions & 2 deletions scalajslib/src/ScalaJSWorkerApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class ScalaJSWorker {
testBridgeInit: Boolean,
fullOpt: Boolean,
moduleKind: ModuleKind,
useECMAScript2015: Boolean
esFeatures: ESFeatures
)(implicit ctx: Ctx.Home): Result[os.Path] = {
bridge(toolsClasspath).link(
sources.items.map(_.toIO).toArray,
Expand All @@ -48,7 +48,7 @@ class ScalaJSWorker {
testBridgeInit,
fullOpt,
moduleKind,
useECMAScript2015
esFeatures
).map(os.Path(_))
}

Expand Down
Loading

0 comments on commit 9c818ae

Please sign in to comment.