Created
June 15, 2017 21:23
-
-
Save sjrd/a60ae67e181d900e1ba52bd18ebdd3ac to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --cc ci/matrix.xml | |
index ca9989d,6772179..0000000 | |
--- a/ci/matrix.xml | |
+++ b/ci/matrix.xml | |
@@@ -99,13 -155,16 +99,13 @@@ | |
<task id="test-suite-ecma-script6"><![CDATA[ | |
setJavaVersion $java | |
+ npm install && | |
sbtretry 'set scalaJSOutputMode in $testSuite := org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript6' \ | |
- 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv().withSourceMap(false)' \ | |
+ 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ | |
++$scala $testSuite/test \ | |
$testSuite/clean && | |
- sbtretry 'set scalaJSOutputMode in noIrCheckTest := org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript6' \ | |
- 'set jsEnv in noIrCheckTest := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ | |
- ++$scala noIrCheckTest/test \ | |
- noIrCheckTest/clean && | |
sbtretry 'set scalaJSOutputMode in $testSuite := org.scalajs.core.tools.linker.backend.OutputMode.ECMAScript6' \ | |
- 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv().withSourceMap(false)' \ | |
+ 'set jsEnv in $testSuite := new org.scalajs.jsenv.nodejs.NodeJSEnv(org.scalajs.jsenv.nodejs.NodeJSEnv.Config().withSourceMap(false))' \ | |
'set scalaJSOptimizerOptions in $testSuite ~= (_.withDisableOptimizer(true))' \ | |
++$scala $testSuite/test \ | |
$testSuite/clean && | |
@@@ -182,9 -238,9 +182,9 @@@ | |
jsEnvs/scalastyle jsEnvsTestKit/scalastyle \ | |
jsEnvsTestSuite/test:scalastyle testAdapter/scalastyle \ | |
sbtPlugin/scalastyle testInterface/scalastyle \ | |
- testSuite/test:scalastyle \ | |
+ testSuite/scalastyle testSuite/test:scalastyle \ | |
testSuiteJVM/test:scalastyle \ | |
- javalibExTestSuite/test:scalastyle helloworld/scalastyle \ | |
+ testSuiteEx/test:scalastyle helloworld/scalastyle \ | |
reversi/scalastyle testingExample/scalastyle \ | |
testingExample/test:scalastyle \ | |
jUnitPlugin/scalastyle jUnitRuntime/scalastyle \ | |
diff --cc cli/src/main/scala/org/scalajs/cli/Scalajsld.scala | |
index 17056cc,f63f871..0000000 | |
--- a/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala | |
+++ b/cli/src/main/scala/org/scalajs/cli/Scalajsld.scala | |
@@@ -161,24 -186,21 +159,20 @@@ object Scalajsld | |
if (options.fullOpt) options.semantics.optimized | |
else options.semantics | |
- val frontendConfig = LinkerFrontend.Config() | |
+ val config = StandardLinker.Config() | |
+ .withSemantics(semantics) | |
+ .withModuleKind(options.moduleKind) | |
+ .withOutputMode(options.outputMode) | |
- .withBypassLinkingErrorsInternal(options.bypassLinkingErrors) | |
.withCheckIR(options.checkIR) | |
- | |
- val backendConfig = LinkerBackend.Config() | |
- .withRelativizeSourceMapBase(options.relativizeSourceMap) | |
- .withPrettyPrint(options.prettyPrint) | |
- | |
- val config = Linker.Config() | |
- .withSourceMap(options.sourceMap) | |
.withOptimizer(!options.noOpt) | |
.withParallel(true) | |
+ .withSourceMap(options.sourceMap) | |
+ .withRelativizeSourceMapBase(options.relativizeSourceMap) | |
.withClosureCompiler(options.fullOpt) | |
- .withFrontendConfig(frontendConfig) | |
- .withBackendConfig(backendConfig) | |
- | |
- val linker = Linker(semantics, options.outputMode, options.moduleKind, | |
- config) | |
+ .withPrettyPrint(options.prettyPrint) | |
+ .withBatchMode(true) | |
+ val linker = StandardLinker(config) | |
val logger = new ScalaConsoleLogger(options.logLevel) | |
val outFile = WritableFileVirtualJSFile(options.output) | |
val cache = (new IRFileCache).newCache | |
diff --cc compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala | |
index 68e11be,5c1138a..0000000 | |
--- a/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala | |
+++ b/compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala | |
@@@ -4232,11 -4212,14 +4238,14 @@@ abstract class GenJSCode extends plugin | |
// Normal call anyway | |
assert(!sym.isClassConstructor, | |
"Trying to call the super constructor of Object in a " + | |
- s"Scala.js-defined JS class at $pos") | |
+ s"non-native JS class at $pos") | |
genApplyMethod(genReceiver, sym, genScalaArgs) | |
} else if (sym.isClassConstructor) { | |
+ assert(genReceiver.isInstanceOf[js.This], | |
+ "Trying to call a JS super constructor with a non-`this` " + | |
+ "receiver at " + pos) | |
js.JSSuperConstructorCall(genJSArgs) | |
- } else if (isScalaJSDefinedJSClass(sym.owner) && !isExposed(sym)) { | |
+ } else if (isNonNativeJSClass(sym.owner) && !isExposed(sym)) { | |
// Reroute to the static method | |
genApplyJSClassMethod(genReceiver, sym, genScalaArgs) | |
} else { | |
diff --cc js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala | |
index ba8dc93,5721647..0000000 | |
--- a/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala | |
+++ b/js-envs/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala | |
diff --cc library/src/main/scala/scala/scalajs/js/Dynamic.scala | |
index a175e53,e374268..0000000 | |
--- a/library/src/main/scala/scala/scalajs/js/Dynamic.scala | |
+++ b/library/src/main/scala/scala/scalajs/js/Dynamic.scala | |
@@@ -76,79 -75,34 +76,79 @@@ sealed trait Dynamic extends js.Any wit | |
/** Factory for dynamically typed JavaScript values. */ | |
object Dynamic { | |
/** Dynamic view of the global scope. */ | |
- @inline def global: Dynamic = scala.scalajs.runtime.environmentInfo.global | |
+ @js.native | |
+ @JSGlobalScope | |
- object global extends js.Any with scala.Dynamic { // scalastyle:ignore | |
++ object global extends js.Any with scala.Dynamic { | |
+ /** Calls a top-level method (in the global scope). */ | |
+ @JSBracketCall | |
+ def applyDynamic(name: String)(args: js.Any*): js.Dynamic = js.native | |
+ | |
+ /** Reads a top-level variable (in the global scope). */ | |
+ @JSBracketAccess | |
+ def selectDynamic(name: String): js.Dynamic = js.native | |
+ | |
+ /** Writes to a top-level variable (in the global scope). */ | |
+ @JSBracketAccess | |
+ def updateDynamic(name: String)(value: js.Any): Unit = js.native | |
+ | |
+ /* The following method is a protection against someone writing | |
+ * `js.Dynamic.global(args)`. It that method were not there, that call | |
+ * would silently desugar into | |
+ * `js.Dynamic.global.applyDynamic("apply")(args)`, which is very | |
+ * unexpected and will produce confusing run-time errors. Better to have | |
+ * a straightforward compile-time error. | |
+ */ | |
+ | |
+ /** Cannot be called--provides a compile-time error instead of a silent | |
+ * run-time error if one tries to do `js.Dynamic.global(something)`. | |
+ */ | |
+ @deprecated("The global scope cannot be called as function.", "forever") | |
+ def apply(args: js.Any*): js.Dynamic = js.native | |
+ } | |
/** Instantiates a new object of a JavaScript class. */ | |
- def newInstance(clazz: Dynamic)(args: Any*): Object with Dynamic = | |
+ def newInstance(clazz: js.Dynamic)(args: js.Any*): js.Object with js.Dynamic = | |
throw new java.lang.Error("stub") | |
/** Creates a new object with a literal syntax. | |
* | |
* For example, | |
+ * {{{ | |
* js.Dynamic.literal(foo = 3, bar = "foobar") | |
+ * }}} | |
* returns the JavaScript object | |
+ * {{{ | |
* {foo: 3, bar: "foobar"} | |
+ * }}} | |
*/ | |
- object literal extends scala.Dynamic { // scalastyle:ignore | |
+ object literal extends scala.Dynamic { | |
- /** literal creation like this: | |
+ /** Literal creation with named arguments. | |
+ * | |
+ * Example: | |
+ * {{{ | |
* js.Dynamic.literal(name1 = "value", name2 = "value") | |
+ * }}} | |
*/ | |
- def applyDynamicNamed(name: String)(fields: (String, Any)*): Object with Dynamic = | |
+ def applyDynamicNamed(name: String)( | |
+ fields: (String, js.Any)*): js.Object with js.Dynamic = { | |
throw new java.lang.Error("stub") | |
+ } | |
- /** literal creation like this: | |
- * js.Dynamic.literal("name1" -> "value", "name2" -> "value") | |
+ /* Note that the `def applyDynamic` could simply be `def apply`, but this | |
+ * would make the `applyDynamicNamed` case fail, since a call with named | |
+ * arguments would be routed to the `def apply`, rather than the dynamic | |
+ * version. | |
+ */ | |
+ | |
+ /** Literal creation with tuples of key/value. | |
* | |
- * Note that this could be simply `def apply`, but this would make the | |
- * applyDynamicNamed fail, since a call with named arguments would | |
- * be routed to the `def apply`, rather than def dynamic version. | |
+ * Example: | |
+ * {{{ | |
+ * js.Dynamic.literal("name1" -> "value", "name2" -> "value") | |
+ * }}} | |
*/ | |
- def applyDynamic(name: String)(fields: (String, Any)*): Object with Dynamic = | |
+ def applyDynamic(name: String)( | |
+ fields: (String, js.Any)*): js.Object with js.Dynamic = { | |
throw new java.lang.Error("stub") | |
} | |
} | |
diff --cc library/src/main/scala/scala/scalajs/js/JSApp.scala | |
index 47fe4b0,a2705e7..0000000 | |
--- a/library/src/main/scala/scala/scalajs/js/JSApp.scala | |
+++ b/library/src/main/scala/scala/scalajs/js/JSApp.scala | |
@@@ -1,14 -1,37 +1,27 @@@ | |
package scala.scalajs.js | |
- /** Base class for top-level, entry point main objects. | |
-import annotation.{JSExport, JSExportDescendentObjects} | |
- | |
+ /** Base class for top-level, entry point main objects (softly deprecated). | |
+ * | |
+ * In Scala.js 1.x, `js.JSApp` will disappear. It is currently "softly" | |
+ * deprecated: it is not recommended to use it in new code, but it does not | |
+ * cause a deprecation warning (yet). Prefer using a standard main method (see | |
+ * below). | |
* | |
- * Objects inheriting from [[JSApp]] are automatically exported to JavaScript | |
- * under their fully qualified name, and their [[main]] method as well. | |
- * | |
* [[JSApp]] is typically used to mark the entry point of a Scala.js | |
* application. As such, the sbt plugin also recognizes top-level objects | |
- * extending [[JSApp]]. It allows to run their [[main]] method with `sbt run`, | |
- * and can also generate a tiny JavaScript launcher snippet executing the | |
- * [[main]] method of one specific [[JSApp]] object. | |
+ * extending [[JSApp]]. It allows to run their [[main]] method with `sbt run`. | |
+ * | |
+ * To execute the [[main]] method immediately when your Scala.js file is | |
+ * loaded, use the `scalaJSUseMainModuleInitializer` setting in the sbt plugin. | |
+ * | |
+ * Starting with Scala.js 0.6.18, the sbt plugin can also recognize "standard" | |
+ * `main` methods of the form | |
+ * {{{ | |
+ * def main(args: Array[String]): Unit = ... | |
+ * }}} | |
+ * in objects, even if they do not extend `JSApp`. Such main methods are | |
+ * cross-platform, and should be preferred over extending `JSApp` in new code. | |
- * Note however that: | |
- * | |
- * - the sbt plugin cannot create a launcher snippet for such objects, and | |
- * - these objects are not automatically exported to JavaScript. | |
*/ | |
-@JSExportDescendentObjects | |
trait JSApp { | |
- @JSExport | |
def main(): Unit | |
} | |
diff --cc partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala | |
index 9331720,9ac74d4..0000000 | |
--- a/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala | |
+++ b/partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala | |
@@@ -2,11 -2,10 +2,9 @@@ package scala.tools.ns | |
/* Super hacky overriding of the MainGenericRunner used by partest */ | |
- import org.scalajs.core.tools.sem.Semantics | |
import org.scalajs.core.tools.logging._ | |
import org.scalajs.core.tools.io._ | |
- import org.scalajs.core.tools.linker.{Linker, ModuleInitializer} | |
- import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} | |
-import org.scalajs.core.tools.io.IRFileCache.IRContainer | |
+ import org.scalajs.core.tools.linker._ | |
import org.scalajs.core.ir | |
diff --cc project/Build.scala | |
index 7d5dc69,5ea90b1..0000000 | |
--- a/project/Build.scala | |
+++ b/project/Build.scala | |
@@@ -437,9 -417,28 +437,26 @@@ object Build | |
) | |
} | |
} | |
+ | |
+ def enableScalastyleInSharedSources: Project = { | |
+ import AddSettings._ | |
+ import org.scalastyle.sbt.ScalastylePlugin.scalastyleSources | |
+ | |
+ project.settings( | |
+ scalastyleSources := (unmanagedSourceDirectories in Compile).value, | |
+ scalastyleSources in Test := (unmanagedSourceDirectories in Test).value, | |
+ SettingKey[String]("foobabar") := scalastyleSources.value.toString | |
+ ).settingSets( | |
+ /* We need to force our settings to be applied *after* settings | |
+ * coming from non-Auto plugins. Because guess what, that's not the | |
+ * default O_o! | |
+ */ | |
+ seq(autoPlugins, nonAutoPlugins, buildScalaFiles, userSettings, defaultSbtFiles) | |
+ ) | |
+ } | |
} | |
- val thisBuildSettings = ( | |
- inScope(Global)(ScalaJSPlugin.globalSettings) | |
- ) ++ Seq( | |
+ val thisBuildSettings = Def.settings( | |
// Most of the projects cross-compile | |
crossScalaVersions := Seq( | |
"2.10.2", | |
@@@ -516,30 -517,33 +533,30 @@@ | |
testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s") | |
) | |
- lazy val irProject: Project = Project( | |
- id = "ir", | |
- base = file("ir"), | |
- settings = commonIrProjectSettings ++ Seq( | |
+ lazy val irProject: Project = Project(id = "ir", base = file("ir")).settings( | |
+ commonIrProjectSettings, | |
libraryDependencies += | |
"com.novocode" % "junit-interface" % "0.9" % "test" | |
-- ) | |
+ ).enableScalastyleInSharedSources | |
lazy val irProjectJS: Project = Project( | |
- id = "irJS", | |
- base = file("ir/.js"), | |
- settings = commonIrProjectSettings ++ myScalaJSSettings ++ Seq( | |
+ id = "irJS", base = file("ir/.js") | |
+ ).enablePlugins( | |
+ MyScalaJSPlugin | |
+ ).settings( | |
+ commonIrProjectSettings, | |
crossVersion := ScalaJSCrossVersion.binary, | |
unmanagedSourceDirectories in Compile += | |
(scalaSource in Compile in irProject).value, | |
unmanagedSourceDirectories in Test += | |
(scalaSource in Test in irProject).value | |
- ) | |
).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( | |
- javalibEx, jUnitRuntime % "test" | |
+ library, jUnitRuntime % "test" | |
- ) | |
+ ).enableScalastyleInSharedSources | |
- lazy val compiler: Project = Project( | |
- id = "compiler", | |
- base = file("compiler"), | |
- settings = commonSettings ++ publishSettings ++ Seq( | |
+ lazy val compiler: Project = project.settings( | |
+ commonSettings, | |
+ publishSettings, | |
name := "Scala.js compiler", | |
crossVersion := CrossVersion.full, // because compiler api is not binary compatible | |
libraryDependencies ++= Seq( | |
@@@ -613,51 -619,46 +630,56 @@@ | |
) ++ ( | |
parallelCollectionsDependencies(scalaVersion.value) | |
) | |
- ).dependsOn(irProject) | |
- ) | |
+ ).dependsOn(irProject).enableScalastyleInSharedSources | |
- lazy val toolsJS: Project = Project( | |
- id = "toolsJS", | |
- base = file("tools/js"), | |
- settings = myScalaJSSettings ++ commonToolsSettings ++ Seq( | |
+ lazy val toolsJS: Project = (project in file("tools/js")).enablePlugins( | |
+ MyScalaJSPlugin | |
+ ).settings( | |
+ commonToolsSettings, | |
crossVersion := ScalaJSCrossVersion.binary, | |
- resourceGenerators in Test += Def.task { | |
- val base = (resourceManaged in Compile).value | |
- IO.createDirectory(base) | |
- val outFile = base / "js-test-definitions.js" | |
+ scalaJSModuleKind in Test := | |
+ org.scalajs.core.tools.linker.backend.ModuleKind.CommonJSModule, | |
+ | |
+ jsExecutionFiles in Test := { | |
val testDefinitions = { | |
org.scalajs.build.HTMLRunnerTemplateAccess.renderTestDefinitions( | |
(loadedTestFrameworks in testSuite in Test).value, | |
(definedTests in testSuite in Test).value) | |
} | |
- IO.write(outFile, testDefinitions) | |
- Seq(outFile) | |
- }.taskValue, | |
+ val testDefinitionsFile = { | |
+ new MemVirtualJSFile("js-test-definitions.js") | |
+ .withContent(testDefinitions) | |
+ } | |
+ | |
+ testDefinitionsFile +: (jsExecutionFiles in Test).value | |
+ }, | |
+ | |
+ testSuiteJSExecutionFilesSetting, | |
// Give more memory to Node.js, and deactivate source maps | |
- jsEnv := new NodeJSEnv(args = Seq("--max_old_space_size=3072")).withSourceMap(false), | |
+ jsEnv := { | |
+ new NodeJSEnv( | |
+ NodeJSEnv.Config() | |
+ .withArgs(List("--max_old_space_size=3072")) | |
+ .withSourceMap(false)) | |
+ }, | |
- jsDependencies += ProvidedJS / "js-test-definitions.js" % "test" | |
- ) ++ inConfig(Test) { | |
- // Redefine test to run Node.js and link HelloWorld | |
+ inConfig(Test) { | |
+ // Redefine test to perform the bootstrap test | |
test := { | |
- val jsEnv = resolvedJSEnv.value | |
- if (!jsEnv.isInstanceOf[NodeJSEnv]) | |
+ if (!jsEnv.value.isInstanceOf[NodeJSEnv]) | |
throw new MessageOnlyException("toolsJS/test must be run with Node.js") | |
- /* Collect IR relevant files from the classpath | |
+ /* We'll explicitly `require` our linked file. Find its module, and | |
+ * remove it from the `jsExecutionFiles` to give to the runner. | |
+ */ | |
+ val toolsTestModule = scalaJSLinkedFile.value | |
+ val executionFiles = | |
+ jsExecutionFiles.value.filter(_ ne toolsTestModule) | |
+ | |
+ /* Collect relevant IR files from the classpath of the test suite. | |
* We assume here that the classpath is valid. This is checked by the | |
* the scalaJSIR task. | |
*/ | |
@@@ -725,22 -726,31 +749,22 @@@ | |
} | |
} | |
).withScalaJSCompiler.dependsOn( | |
- javalibEx, testSuite % "test->test", irProjectJS | |
+ library, irProjectJS, jUnitRuntime % "test" | |
- ) | |
+ ).enableScalastyleInSharedSources | |
- lazy val jsEnvs: Project = Project( | |
- id = "jsEnvs", | |
- base = file("js-envs"), | |
- settings = ( | |
- commonSettings ++ publishSettings ++ fatalWarningsSettings | |
- ) ++ Seq( | |
+ lazy val jsEnvs: Project = (project in file("js-envs")).settings( | |
+ commonSettings, | |
+ publishSettings, | |
+ fatalWarningsSettings, | |
name := "Scala.js JS Envs", | |
- libraryDependencies ++= Seq( | |
- "io.apigee" % "rhino" % "1.7R5pre4", | |
- "org.webjars" % "envjs" % "1.2" | |
- ) ++ ScalaJSPluginInternal.phantomJSJettyModules.map(_ % "provided"), | |
previousArtifactSetting, | |
mimaBinaryIssueFilters ++= BinaryIncompatibilities.JSEnvs | |
- ) | |
).dependsOn(tools) | |
- lazy val jsEnvsTestKit: Project = Project( | |
- id = "jsEnvsTestKit", | |
- base = file("js-envs-test-kit"), | |
- settings = ( | |
- commonSettings ++ publishSettings ++ fatalWarningsSettings | |
- ) ++ Seq( | |
+ lazy val jsEnvsTestKit: Project = (project in file("js-envs-test-kit")).settings( | |
+ commonSettings, | |
+ publishSettings, | |
+ fatalWarningsSettings, | |
name := "Scala.js JS Envs Test Kit", | |
libraryDependencies += | |
"junit" % "junit" % "4.8.2", | |
@@@ -1158,29 -1211,33 +1182,29 @@@ | |
) | |
) | |
- lazy val jUnitTestOutputsJS = Project( | |
- id = "jUnitTestOutputsJS", | |
- base = file("junit-test/output-js"), | |
- settings = commonJUnitTestOutputsSettings ++ myScalaJSSettings ++ Seq( | |
+ lazy val jUnitTestOutputsJS = (project in file("junit-test/output-js")).enablePlugins( | |
+ MyScalaJSPlugin | |
+ ).settings( | |
+ commonJUnitTestOutputsSettings, | |
name := "Tests for Scala.js JUnit output in JS." | |
- ) | |
).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( | |
jUnitRuntime % "test", testInterface % "test" | |
- ) | |
+ ).enableScalastyleInSharedSources | |
- lazy val jUnitTestOutputsJVM = Project( | |
- id = "jUnitTestOutputsJVM", | |
- base = file("junit-test/output-jvm"), | |
- settings = commonJUnitTestOutputsSettings ++ Seq( | |
+ lazy val jUnitTestOutputsJVM = (project in file("junit-test/output-jvm")).settings( | |
+ commonJUnitTestOutputsSettings, | |
name := "Tests for Scala.js JUnit output in JVM.", | |
libraryDependencies ++= Seq( | |
"org.scala-sbt" % "test-interface" % "1.0" % "test", | |
"com.novocode" % "junit-interface" % "0.11" % "test" | |
) | |
-- ) | |
+ ).enableScalastyleInSharedSources | |
- lazy val jUnitPlugin = Project( | |
- id = "jUnitPlugin", | |
- base = file("junit-plugin"), | |
- settings = commonSettings ++ publishSettings ++ fatalWarningsSettings ++ Seq( | |
+ lazy val jUnitPlugin = (project in file("junit-plugin")).settings( | |
+ commonSettings, | |
+ publishSettings, | |
+ fatalWarningsSettings, | |
name := "Scala.js JUnit test plugin", | |
crossVersion := CrossVersion.full, | |
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value, | |
@@@ -1521,37 -1618,53 +1545,47 @@@ | |
"org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration", | |
"main1") | |
}, | |
+ scalaJSModuleInitializers in Test += { | |
+ ModuleInitializer.mainMethodWithArgs( | |
+ "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration", | |
+ "mainArgs1") | |
+ }, | |
+ scalaJSModuleInitializers in Test += { | |
+ ModuleInitializer.mainMethodWithArgs( | |
+ "org.scalajs.testsuite.compiler.ModuleInitializerInTestConfiguration", | |
+ "mainArgs2", List("foo", "bar")) | |
- } | |
- ) | |
++ }, | |
+ | |
+ testSuiteTestHtmlSetting | |
).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn( | |
library, jUnitRuntime | |
- ) | |
+ ).enableScalastyleInSharedSources | |
- lazy val testSuiteJVM: Project = Project( | |
- id = "testSuiteJVM", | |
- base = file("test-suite/jvm"), | |
- settings = commonSettings ++ testSuiteCommonSettings(isJSTest = false) ++ Seq( | |
+ lazy val testSuiteJVM: Project = (project in file("test-suite/jvm")).settings( | |
+ commonSettings, | |
+ testSuiteCommonSettings(isJSTest = false), | |
name := "Scala.js test suite on JVM", | |
libraryDependencies += | |
"com.novocode" % "junit-interface" % "0.11" % "test" | |
-- ) | |
+ ).enableScalastyleInSharedSources | |
- lazy val noIrCheckTest: Project = Project( | |
- id = "noIrCheckTest", | |
- base = file("no-ir-check-test"), | |
- settings = commonSettings ++ myScalaJSSettings ++ testTagSettings ++ Seq( | |
- name := "Scala.js not IR checked tests", | |
- scalaJSOptimizerOptions ~= (_. | |
- withCheckScalaJSIR(false). | |
- withBypassLinkingErrors(true) | |
- ), | |
- testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), | |
- publishArtifact in Compile := false | |
- ) | |
- ).withScalaJSCompiler.withScalaJSJUnitPlugin.dependsOn(library, jUnitRuntime) | |
- | |
- lazy val javalibExTestSuite: Project = Project( | |
- id = "javalibExTestSuite", | |
- base = file("javalib-ex-test-suite"), | |
- settings = ( | |
- commonSettings ++ myScalaJSSettings ++ testTagSettings | |
- ) ++ Seq( | |
- name := "JavaLib Ex Test Suite", | |
+ /* Additional test suite, for tests that should not be part of the normal | |
+ * test suite for various reasons. The most common reason is that the tests | |
+ * in there "fail to fail" if they happen in the larger test suite, due to | |
+ * all the other code that's there (can have impact on dce, optimizations, | |
+ * GCC, etc.). | |
+ * | |
+ * TODO Ideally, we should have a mechanism to separately compile, link and | |
+ * test each file in this test suite, so that we're sure that do not | |
+ * interfere with other. | |
+ */ | |
+ lazy val testSuiteEx: Project = (project in file("test-suite-ex")).enablePlugins( | |
+ MyScalaJSPlugin | |
+ ).settings( | |
+ commonSettings, | |
+ testTagSettings, | |
+ name := "Scala.js test suite ex", | |
publishArtifact in Compile := false, | |
testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a", "-s"), | |
scalacOptions in Test ~= (_.filter(_ != "-deprecation")) | |
diff --cc sbt-plugin-test/build.sbt | |
index cc692e1,c94eb52..0000000 | |
--- a/sbt-plugin-test/build.sbt | |
+++ b/sbt-plugin-test/build.sbt | |
diff --cc sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala | |
index 8eaa9ca,bfb32a1..0000000 | |
--- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala | |
+++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/OptimizerOptions.scala | |
diff --cc sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala | |
index 93c0190,4ebc31a..0000000 | |
--- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala | |
+++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala | |
@@@ -9,26 -9,42 +9,27 @@@ | |
package org.scalajs.sbtplugin | |
+import scala.language.implicitConversions | |
+ | |
import sbt._ | |
+import sbtcrossproject._ | |
+ | |
import org.scalajs.core.tools.sem.Semantics | |
import org.scalajs.core.tools.io._ | |
- import org.scalajs.core.tools.linker.{ModuleInitializer, LinkingUnit} | |
- import org.scalajs.core.tools.linker.backend.{ModuleKind, OutputMode} | |
+ import org.scalajs.core.tools.linker._ | |
+ import org.scalajs.core.tools.linker.standard._ | |
-import org.scalajs.core.tools.jsdep.{JSDependencyManifest, ResolvedJSDependency} | |
-import org.scalajs.core.tools.jsdep.ManifestFilters.ManifestFilter | |
-import org.scalajs.core.tools.jsdep.DependencyResolver.DependencyFilter | |
import org.scalajs.core.ir.ScalaJSVersions | |
import org.scalajs.jsenv.{JSEnv, JSConsole} | |
- import org.scalajs.jsenv.nodejs.{NodeJSEnv, JSDOMNodeJSEnv} | |
-import org.scalajs.jsenv.rhino.RhinoJSEnv | |
+ import org.scalajs.jsenv.nodejs.NodeJSEnv | |
+ import org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv | |
-import org.scalajs.jsenv.phantomjs.PhantomJSEnv | |
object ScalaJSPlugin extends AutoPlugin { | |
override def requires: Plugins = plugins.JvmPlugin | |
- object autoImport { // scalastyle:ignore | |
- /* The following module-case double definition is a workaround for a bug | |
- * somewhere in the sbt dependency macro - scala macro pipeline that affects | |
- * the %%% operator on dependencies (see #1331). | |
- * | |
- * If the object AutoImport is written lower-case, it is wrongly identified as | |
- * dynamic dependency (only if the usage code is generated by a macro). On the | |
- * other hand, only lower-case autoImport is automatically imported by sbt (in | |
- * an AutoPlugin, therefore the alias. | |
- * | |
- * We do not know *why* this fixes the issue, but it does. | |
- */ | |
- val autoImport = AutoImport | |
- | |
- object AutoImport extends impl.DependencyBuilders | |
- with cross.CrossProjectExtra { | |
++ object autoImport { | |
import KeyRanks._ | |
// Some constants | |
@@@ -113,9 -154,45 +118,13 @@@ | |
args: Seq[String] = Seq.empty, | |
env: Map[String, String] = Map.empty | |
): Def.Initialize[Task[JSDOMNodeJSEnv]] = Def.task { | |
- new JSDOMNodeJSEnv(executable, args, env) | |
+ new JSDOMNodeJSEnv( | |
+ org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv.Config() | |
+ .withExecutable(executable) | |
+ .withArgs(args.toList) | |
+ .withEnv(env)) | |
} | |
- /** | |
- * Creates a [[sbt.Def.Initialize Def.Initialize]] for a PhantomJSEnv. Use | |
- * this to explicitly specify in your build that you would like to run with | |
- * PhantomJS: | |
- * | |
- * {{{ | |
- * jsEnv := PhantomJSEnv().value | |
- * }}} | |
- * | |
- * Note that the resulting [[sbt.Def.Setting Setting]] is not scoped at | |
- * all, but must be scoped in a project that has the ScalaJSPlugin enabled | |
- * to work properly. | |
- * Therefore, either put the upper line in your project settings (common | |
- * case) or scope it manually, using | |
- * [[sbt.ProjectExtra.inScope[* Project.inScope]]. | |
- */ | |
- def PhantomJSEnv( | |
- executable: String = "phantomjs", | |
- args: Seq[String] = Seq.empty, | |
- env: Map[String, String] = Map.empty, | |
- autoExit: Boolean = true | |
- ): Def.Initialize[Task[PhantomJSEnv]] = Def.task { | |
- val loader = scalaJSPhantomJSClassLoader.value | |
- new PhantomJSEnv( | |
- org.scalajs.jsenv.phantomjs.PhantomJSEnv.Config() | |
- .withExecutable(executable) | |
- .withArgs(args.toList) | |
- .withEnv(env) | |
- .withAutoExit(autoExit) | |
- .withJettyClassLoader(loader)) | |
- } | |
- | |
// ModuleKind | |
val ModuleKind = org.scalajs.core.tools.linker.backend.ModuleKind | |
@@@ -147,6 -232,14 +156,11 @@@ | |
"`scalaJSUseMainModuleInitializer` is true", | |
CTask) | |
+ val scalaJSLinkerConfig = SettingKey[StandardLinker.Config]( | |
+ "scalaJSLinkerConfig", | |
+ "Configuration of the Scala.js linker", | |
+ BPlusSetting) | |
+ | |
- val scalaJSNativeLibraries = TaskKey[Attributed[Seq[VirtualJSFile with RelativeVirtualFile]]]( | |
- "scalaJSNativeLibraries", "All the *.js files on the classpath", CTask) | |
- | |
val scalaJSStage = SettingKey[Stage]("scalaJSStage", | |
"The optimization stage at which run and test are executed", APlusSetting) | |
diff --cc sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | |
index 222c95b,c3fb38a..0000000 | |
--- a/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | |
+++ b/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala | |
@@@ -10,18 -10,17 +10,16 @@@ import Cache.seqForma | |
import complete.Parser | |
import complete.DefaultParsers._ | |
+import sbtcrossproject.CrossPlugin.autoImport._ | |
+ | |
import Loggers._ | |
--import org.scalajs.core.tools.sem.Semantics | |
-import org.scalajs.core.tools.io.{IO => toolsIO, _} | |
-import org.scalajs.core.tools.jsdep._ | |
-import org.scalajs.core.tools.json._ | |
+import org.scalajs.core.tools.io.{IO => _, _} | |
- import org.scalajs.core.tools.linker.{ClearableLinker, ModuleInitializer, Linker} | |
- import org.scalajs.core.tools.linker.frontend.LinkerFrontend | |
- import org.scalajs.core.tools.linker.backend.{LinkerBackend, ModuleKind, OutputMode} | |
+ import org.scalajs.core.tools.linker._ | |
+ import org.scalajs.core.tools.linker.standard._ | |
import org.scalajs.jsenv._ | |
-import org.scalajs.jsenv.phantomjs.PhantomJettyClassLoader | |
+import org.scalajs.jsenv.nodejs.NodeJSEnv | |
import org.scalajs.core.ir | |
import org.scalajs.core.ir.Utils.escapeJS | |
@@@ -149,28 -197,42 +160,41 @@@ object ScalaJSPluginInternal | |
else | |
None | |
} | |
+ val newConfigRelSourceMapBase = | |
+ (scalaJSLinkerConfig in key).value.relativizeSourceMapBase | |
+ val relSourceMapBase = | |
+ newConfigRelSourceMapBase.orElse(oldConfigRelSourceMapBase) | |
- val frontendConfig = LinkerFrontend.Config() | |
+ StandardLinker.Config() | |
+ .withSemantics(semantics) | |
+ .withModuleKind(moduleKind) | |
+ .withOutputMode(outputMode) | |
- .withBypassLinkingErrorsInternal(opts.bypassLinkingErrors) | |
.withCheckIR(opts.checkScalaJSIR) | |
- | |
- val backendConfig = LinkerBackend.Config() | |
+ .withOptimizer(!opts.disableOptimizer) | |
+ .withParallel(opts.parallel) | |
+ .withSourceMap(withSourceMap) | |
.withRelativizeSourceMapBase(relSourceMapBase) | |
+ .withClosureCompiler(opts.useClosureCompiler) | |
.withCustomOutputWrapperInternal(scalaJSOutputWrapperInternal.value) | |
.withPrettyPrint(opts.prettyPrintFullOptJS) | |
+ .withBatchMode(opts.batchMode) | |
+ }, | |
- val config = Linker.Config() | |
- .withSourceMap(withSourceMap) | |
- .withOptimizer(!opts.disableOptimizer) | |
- .withParallel(opts.parallel) | |
- .withClosureCompiler(opts.useClosureCompiler) | |
- .withFrontendConfig(frontendConfig) | |
- .withBackendConfig(backendConfig) | |
+ scalaJSLinker in key := { | |
+ val config = (scalaJSLinkerConfig in key).value | |
- val newLinker = { () => | |
- Linker(semantics, outputMode, moduleKind, config) | |
+ if (config.moduleKind != scalaJSModuleKind.value) { | |
+ val projectID = thisProject.value.id | |
+ val configName = configuration.value.name | |
+ val keyName = key.key.label | |
+ sLog.value.warn( | |
+ s"The module kind in `scalaJSLinkerConfig in ($projectID, " + | |
+ s"$configName, $keyName)` is different than the value of " + | |
+ s"`scalaJSModuleKind in ($projectID, $configName)`. " + | |
+ "Some things will go wrong.") | |
} | |
- new ClearableLinker(newLinker, opts.batchMode) | |
+ new ClearableLinker(() => StandardLinker(config), config.batchMode) | |
}, | |
usesScalaJSLinkerTag in key := { | |
@@@ -223,9 -294,11 +256,9 @@@ | |
val sourceMapFile = FileVirtualJSFile(output).sourceMapFile | |
Attributed.blank(output).put(scalaJSSourceMap, sourceMapFile) | |
- } tag((usesScalaJSLinkerTag in key).value) | |
+ }.tag(usesLinkerTag) | |
}.value, | |
- key := key.dependsOn(packageJSDependencies, packageScalaJSLauncherInternal).value, | |
- | |
scalaJSLinkedFile in key := new FileVirtualJSFile(key.value.data) | |
) | |
@@@ -416,10 -677,39 +449,10 @@@ | |
} | |
}, | |
- loadedJSEnv := Def.taskDyn { | |
- val log = streams.value.log | |
- val libs = | |
- resolvedJSDependencies.value.data ++ scalaJSConfigurationLibs.value | |
- resolvedJSEnv.value match { | |
- /* Do not apply the LinkingUnitJSEnv treatment when | |
- * scalaJSModuleKind != NoModule, because the API of LinkingUnitJSEnv | |
- * is not designed to deal with modules, and would ignore that | |
- * setting. | |
- */ | |
- case env: LinkingUnitJSEnv | |
- if scalaJSModuleKind.value == ModuleKind.NoModule => | |
- log.debug(s"Generating LinkingUnit for JSEnv ${env.name}") | |
- Def.task { | |
- val linker = scalaJSLinker.value | |
- val ir = scalaJSIR.value.data | |
- val moduleInitializers = scalaJSModuleInitializers.value | |
- val unit = linker.linkUnit(ir, moduleInitializers, | |
- env.symbolRequirements, sbtLogger2ToolsLogger(log)) | |
- | |
- log.debug("Loading JSEnv with LinkingUnit") | |
- env.loadLibs(libs).loadLinkingUnit(unit) | |
- } tag(usesScalaJSLinkerTag.value) | |
- case env => | |
- Def.task { | |
- val file = scalaJSLinkedFile.value | |
- log.debug(s"Loading JSEnv with linked file ${file.path}") | |
- env.loadLibs(libs :+ ResolvedJSDependency.minimal(file)) | |
- } | |
- } | |
- }.value, | |
+ // Crucially, add the Scala.js linked file to the JS files | |
+ jsExecutionFiles += scalaJSLinkedFile.value, | |
- scalaJSModuleIdentifier := Def.taskDyn[Option[String]] { | |
+ scalaJSModuleIdentifier := Def.settingDyn[Task[Option[String]]] { | |
scalaJSModuleKind.value match { | |
case ModuleKind.NoModule => | |
Def.task { | |
@@@ -450,7 -759,21 +483,15 @@@ | |
} | |
} | |
- private def memLauncher(mainCl: String, moduleKind: ModuleKind, | |
- moduleIdentifier: Option[String]): VirtualJSFile = { | |
- new MemVirtualJSFile("Generated launcher file") | |
- .withContent(launcherContent(mainCl, moduleKind, moduleIdentifier)) | |
- } | |
- | |
+ @deprecated("js.JSApps are going away, and this method with them.", "0.6.18") | |
def discoverJSApps(analysis: inc.Analysis): Seq[String] = { | |
+ discoverScalaJSMainClasses(analysis).collect { | |
+ case (name, false) => name | |
+ }.toList | |
+ } | |
+ | |
+ private def discoverScalaJSMainClasses( | |
+ analysis: inc.Analysis): Map[String, Boolean] = { | |
import xsbt.api.{Discovered, Discovery} | |
val jsApp = "scala.scalajs.js.JSApp" | |
@@@ -493,9 -835,38 +553,6 @@@ | |
} | |
}, | |
- discoveredMainClasses := compile.map(discoverJSApps). | |
- storeAs(discoveredMainClasses).triggeredBy(compile).value, | |
- mainClass in scalaJSLauncherInternal := (mainClass in run).value, | |
- scalaJSLauncherInternal := Def.settingDyn[Task[Attributed[VirtualJSFile]]] { | |
- if (persistLauncherInternal.value) { | |
- Def.task { | |
- packageScalaJSLauncherInternal.value.map(FileVirtualJSFile) | |
- } | |
- } else if (scalaJSUseMainModuleInitializer.value) { | |
- Def.task { | |
- val base = Attributed.blank[VirtualJSFile]( | |
- new MemVirtualJSFile("No-op generated launcher file")) | |
- mainClass.value.fold { | |
- base | |
- } { mainClass => | |
- base.put(name.key, mainClass) | |
- } | |
- } | |
- } else { | |
- Def.task { | |
- (mainClass in scalaJSLauncherInternal).value.fold { | |
- throw new MessageOnlyException("No main class detected.") | |
- } { mainClass => | |
- val moduleKind = scalaJSModuleKind.value | |
- val moduleIdentifier = scalaJSModuleIdentifier.value | |
- val memLaunch = | |
- memLauncher(mainClass, moduleKind, moduleIdentifier) | |
- Attributed[VirtualJSFile](memLaunch)( | |
- AttributeMap.empty.put(name.key, mainClass)) | |
- } | |
- } | |
- } | |
- }.value, | |
-- | |
run := { | |
// use assert to prevent warning about pure expr in stat pos | |
assert(scalaJSEnsureUnforked.value) | |
@@@ -632,19 -1032,69 +689,61 @@@ | |
) | |
val scalaJSProjectBaseSettings = Seq( | |
- isScalaJSProject := true, | |
+ crossPlatform := JSPlatform, | |
+ /* We first define scalaJSLinkerConfig in the project scope, with all | |
+ * the defaults. Later, we derive all the old config options in the | |
+ * project scope from scalaJSLinkerConfig. | |
+ * | |
+ * At the end of the day, in the fully qualified scope | |
+ * (project, config, linkKey), we re-derive scalaJSLinkerConfig from all | |
+ * the old config keys. | |
+ * | |
+ * This effectively gives meaning to scalaJSLinkerConfig in the project | |
+ * scope and in the fully qualified scope, but not in-between. Changes | |
+ * to `scalaJSLinkerConfig in (project, config)` will not have any | |
+ * effect. | |
+ * | |
+ * This is a compromise to ensure backward compatibility of using the old | |
+ * options in all cases, and a reasonable way to use the new options | |
+ * for typical use cases. | |
+ * | |
+ * `relativeSourceMaps`/`scalaJSLinkerConfig.relativizeSourceMapBase` is | |
+ * an exception. We cannot derive `relativizeSourceMapBase` only from | |
+ * `relativeSourceMaps`, and deriving `relativeSourceMaps` from | |
+ * `relativizeSourceMapBase` would lose information. Instead, we keep | |
+ * `relativeSourceMaps` to its default `false` in the project scope, | |
+ * irrespective of `scalaJSLinkerConfig`. And in the fully qualified | |
+ * scope, *if* `relativeSourceMaps` is true, we set | |
+ * `relativeSourceMapBase`, otherwise we leave it untouched. This | |
+ * provides the same compatibility/usability features. | |
+ */ | |
+ scalaJSLinkerConfig := { | |
+ StandardLinker.Config() | |
+ .withParallel(OptimizerOptions.DefaultParallel) | |
+ }, | |
+ | |
relativeSourceMaps := false, | |
- persistLauncherInternal := false, | |
- persistLauncherInternal in Test := false, | |
- emitSourceMaps := true, | |
+ emitSourceMaps := scalaJSLinkerConfig.value.sourceMap, | |
- scalaJSOutputWrapperInternal := ("", ""), | |
+ scalaJSOutputWrapperInternal := | |
+ scalaJSLinkerConfig.value.customOutputWrapper, | |
- scalaJSOptimizerOptions := OptimizerOptions(), | |
+ scalaJSOptimizerOptions := { | |
+ val config = scalaJSLinkerConfig.value | |
+ OptimizerOptions() | |
- .withBypassLinkingErrorsInternal(config.bypassLinkingErrors) | |
+ .withParallel(config.parallel) | |
+ .withBatchMode(config.batchMode) | |
+ .withDisableOptimizer(!config.optimizer) | |
+ .withPrettyPrintFullOptJS(config.prettyPrint) | |
+ .withCheckScalaJSIR(config.checkIR) | |
+ .withUseClosureCompiler(config.closureCompiler) | |
+ }, | |
- scalaJSSemantics := Semantics.Defaults, | |
- scalaJSOutputMode := OutputMode.ECMAScript51Isolated, | |
- scalaJSModuleKind := ModuleKind.NoModule, | |
- jsDependencies := Seq(), | |
- jsDependencyFilter := identity, | |
- jsManifestFilter := identity, | |
- | |
+ scalaJSSemantics := scalaJSLinkerConfig.value.semantics, | |
+ scalaJSOutputMode := scalaJSLinkerConfig.value.outputMode, | |
+ scalaJSModuleKind := scalaJSLinkerConfig.value.moduleKind, | |
- checkScalaJSSemantics := true, | |
scalaJSModuleInitializers := Seq(), | |
scalaJSModuleInitializers in Compile := scalaJSModuleInitializers.value, | |
diff --cc test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/MathTestOnJDK8.scala | |
index 3d0e356,267cad6..0000000 | |
--- a/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/MathTestOnJDK8.scala | |
+++ b/test-suite/shared/src/test/require-jdk8/org/scalajs/testsuite/javalib/lang/MathTestOnJDK8.scala | |
diff --cc tools/js/src/test/scala/org/scalajs/core/tools/test/js/QuickLinker.scala | |
index 3ece296,78304db..0000000 | |
--- a/tools/js/src/test/scala/org/scalajs/core/tools/test/js/QuickLinker.scala | |
+++ b/tools/js/src/test/scala/org/scalajs/core/tools/test/js/QuickLinker.scala | |
@@@ -1,11 -1,8 +1,9 @@@ | |
package org.scalajs.core.tools.test.js | |
+import java.io.InputStream | |
+ | |
- import org.scalajs.core.tools.sem.Semantics | |
import org.scalajs.core.tools.io._ | |
- import org.scalajs.core.tools.linker.{ModuleInitializer, Linker} | |
- import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind} | |
-import org.scalajs.core.tools.io.IRFileCache.IRContainer | |
+ import org.scalajs.core.tools.linker._ | |
import org.scalajs.core.tools.logging._ | |
import scala.scalajs.js | |
@@@ -72,59 -67,32 +67,87 @@@ object QuickLinker | |
out.content | |
} | |
+ private def parseModuleInitializer(spec: String): ModuleInitializer = { | |
+ def fail(): Nothing = { | |
+ throw new IllegalArgumentException( | |
+ s"'$spec' is not a valid module initializer spec") | |
+ } | |
+ | |
+ def parseObjectAndMain(str: String): (String, String) = { | |
+ val lastDot = str.lastIndexOf('.') | |
+ if (lastDot < 0) | |
+ fail() | |
+ (str.substring(0, lastDot), str.substring(lastDot + 1)) | |
+ } | |
+ | |
+ val parenPos = spec.indexOf('(') | |
+ if (parenPos < 0) { | |
+ val (objectName, mainMethodName) = parseObjectAndMain(spec) | |
+ ModuleInitializer.mainMethod(objectName, mainMethodName) | |
+ } else { | |
+ if (spec.last != ')') | |
+ fail() | |
+ val (objectName, mainMethodName) = | |
+ parseObjectAndMain(spec.substring(0, parenPos)) | |
+ val args = | |
+ spec.substring(parenPos + 1, spec.length - 1).split(",", -1).toList | |
+ ModuleInitializer.mainMethodWithArgs(objectName, mainMethodName, args) | |
+ } | |
+ } | |
+ | |
+ private class NodeVirtualJarFile(file: String) | |
+ extends NodeVirtualBinaryFile(file) with VirtualFileContainer { | |
+ | |
+ def listEntries[T](p: String => Boolean)( | |
+ makeResult: (String, InputStream) => T): List[T] = { | |
+ import js.Dynamic.{global => g} | |
+ | |
+ val stream = inputStream | |
+ try { | |
+ /* Build a Uint8Array with the content of this jar file. | |
+ * We know that in practice, NodeVirtualBinaryFile#inputStream returns | |
+ * an ArrayBufferInputStream, so we just fetch its internal ArrayBuffer | |
+ * rather than copying. | |
+ * | |
+ * Since we have NodeVirtualBinaryFile under our control, in the same | |
+ * repository, we can make this assumption. Should we change | |
+ * NodeVirtualBinaryFile, this test will immediately fail, and we can | |
+ * adapt it. | |
+ */ | |
+ val data = stream match { | |
+ case stream: ArrayBufferInputStream => | |
+ // Simulate reading all the data | |
+ while (stream.skip(stream.available()) > 0) {} | |
+ new Uint8Array(stream.buffer, stream.offset, stream.length) | |
+ case _ => | |
+ throw new AssertionError( | |
+ s"Uh! '$file' was not read as an ArrayBufferInputStream") | |
+ } | |
+ | |
+ val zip = new JSZip(data) | |
+ | |
+ for ((name, entry) <- zip.files.toList if p(name)) yield { | |
+ val entryStream = new ArrayBufferInputStream(entry.asArrayBuffer()) | |
+ try { | |
+ makeResult(name, entryStream) | |
+ } finally { | |
+ entryStream.close() | |
+ } | |
+ } | |
+ } finally { | |
+ stream.close() | |
+ } | |
+ } | |
+ } | |
+ | |
+ @js.native | |
+ @JSImport("jszip", JSImport.Default) | |
+ private class JSZip(data: Uint8Array) extends js.Object { | |
+ def files: js.Dictionary[JSZipEntry] = js.native | |
+ } | |
+ | |
+ private trait JSZipEntry extends js.Object { | |
+ def asArrayBuffer(): ArrayBuffer | |
+ } | |
+ | |
} | |
diff --cc tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Emitter.scala | |
index 1ab8445,30cab7a..0000000 | |
--- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Emitter.scala | |
+++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/Emitter.scala | |
@@@ -17,8 -17,6 +17,7 @@@ import org.scalajs.core.ir.{ClassKind, | |
import org.scalajs.core.ir.Trees.JSNativeLoadSpec | |
import org.scalajs.core.ir.Definitions.decodeClassName | |
+import org.scalajs.core.tools.io._ | |
- import org.scalajs.core.tools.sem._ | |
import org.scalajs.core.tools.logging._ | |
import org.scalajs.core.tools.javascript.{Trees => js, _} | |
diff --cc tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/FunctionEmitter.scala | |
index 6097211,c3eedd4..0000000 | |
--- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/FunctionEmitter.scala | |
+++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/backend/emitter/FunctionEmitter.scala | |
@@@ -2309,40 -2210,6 +2308,29 @@@ private[emitter] class FunctionEmitter( | |
} | |
} | |
+ private def transformLabelIdent(ident: Ident): js.Ident = | |
+ js.Ident(ident.name, ident.originalName)(ident.pos) | |
+ | |
+ private def transformPropIdent(ident: Ident): js.Ident = | |
+ js.Ident(ident.name, ident.originalName)(ident.pos) | |
+ | |
+ private def transformLocalVarIdent(ident: Ident): js.Ident = | |
+ js.Ident(transformLocalName(ident.name), ident.originalName)(ident.pos) | |
+ | |
+ private def transformGlobalVarIdent(ident: Ident): js.Ident = { | |
+ referenceGlobalName(ident.name) | |
+ js.Ident(ident.name, ident.originalName)(ident.pos) | |
+ } | |
+ | |
- def genClassDataOf(cls: ReferenceType)(implicit pos: Position): js.Tree = { | |
- cls match { | |
- case ClassType(className) => | |
- envField("d", className) | |
- case ArrayType(base, dims) => | |
- (1 to dims).foldLeft[js.Tree](envField("d", base)) { (prev, _) => | |
- js.Apply(js.DotSelect(prev, js.Ident("getArrayOf")), Nil) | |
- } | |
- } | |
- } | |
- | |
+ /* In FunctionEmitter, we must always keep all global var names, not only | |
+ * dangerous ones. This helper makes it less annoying. | |
+ */ | |
+ private def genRawJSClassConstructor(className: String)( | |
+ implicit pos: Position): WithGlobals[js.Tree] = { | |
+ jsGen.genRawJSClassConstructor(className, | |
+ keepOnlyDangerousVarNames = false) | |
+ } | |
+ | |
private def genFround(arg: js.Tree)(implicit pos: Position): js.Tree = { | |
genCallHelper("fround", arg) | |
} | |
diff --git a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/ConsoleTestRunner.scala b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/ConsoleTestRunner.scala | |
index d825ffa..04352c4 100644 | |
--- a/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/ConsoleTestRunner.scala | |
+++ b/test-suite/js/src/main/scala/org/scalajs/testsuite/utils/ConsoleTestRunner.scala | |
@@ -54,7 +54,7 @@ object ConsoleTestRunner { | |
def failedEvents: List[Event] = _failedEvents.toList | |
- def handle(ev: Event) = { | |
+ def handle(ev: Event): Unit = { | |
if (ev.status == Status.Error || ev.status == Status.Failure) | |
_failedEvents += ev | |
} | |
diff --git a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/StandardLinker.scala b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/StandardLinker.scala | |
index 8c9f68e..1b5fa40 100644 | |
--- a/tools/shared/src/main/scala/org/scalajs/core/tools/linker/StandardLinker.scala | |
+++ b/tools/shared/src/main/scala/org/scalajs/core/tools/linker/StandardLinker.scala | |
@@ -20,7 +20,6 @@ object StandardLinker { | |
def apply(config: Config): Linker = { | |
val frontendConfig = LinkerFrontend.Config() | |
- .withBypassLinkingErrorsInternal(config.bypassLinkingErrors) | |
.withCheckIR(config.checkIR) | |
val backendConfig = LinkerBackend.Config() | |
@@ -49,8 +48,6 @@ object StandardLinker { | |
val semantics: Semantics, | |
/** Module kind. */ | |
val moduleKind: ModuleKind, | |
- /** Whether to only warn if the linker has errors. */ | |
- val bypassLinkingErrors: Boolean, | |
/** If true, performs expensive checks of the IR for the used parts. */ | |
val checkIR: Boolean, | |
/** Whether to use the Scala.js optimizer. */ | |
@@ -90,7 +87,6 @@ object StandardLinker { | |
this( | |
semantics = Semantics.Defaults, | |
moduleKind = ModuleKind.NoModule, | |
- bypassLinkingErrors = false, | |
checkIR = false, | |
optimizer = true, | |
parallel = true, | |
@@ -113,18 +109,6 @@ object StandardLinker { | |
def withModuleKind(moduleKind: ModuleKind): Config = | |
copy(moduleKind = moduleKind) | |
- @deprecated( | |
- "Bypassing linking errors will not be possible in the next major version.", | |
- "0.6.6") | |
- def withBypassLinkingErrors(bypassLinkingErrors: Boolean): Config = | |
- copy(bypassLinkingErrors = bypassLinkingErrors) | |
- | |
- // Non-deprecated version to call from the sbt plugin | |
- private[scalajs] def withBypassLinkingErrorsInternal( | |
- bypassLinkingErrors: Boolean): Config = { | |
- copy(bypassLinkingErrors = bypassLinkingErrors) | |
- } | |
- | |
def withCheckIR(checkIR: Boolean): Config = | |
copy(checkIR = checkIR) | |
@@ -170,7 +154,6 @@ object StandardLinker { | |
s"""StandardLinker.Config( | |
| semantics = $semantics, | |
| moduleKind = $moduleKind, | |
- | bypassLinkingErrors = $bypassLinkingErrors, | |
| checkIR = $checkIR, | |
| optimizer = $optimizer, | |
| parallel = $parallel, | |
@@ -187,7 +170,6 @@ object StandardLinker { | |
private def copy( | |
semantics: Semantics = semantics, | |
moduleKind: ModuleKind = moduleKind, | |
- bypassLinkingErrors: Boolean = bypassLinkingErrors, | |
checkIR: Boolean = checkIR, | |
optimizer: Boolean = optimizer, | |
parallel: Boolean = parallel, | |
@@ -202,7 +184,6 @@ object StandardLinker { | |
new Config( | |
semantics, | |
moduleKind, | |
- bypassLinkingErrors, | |
checkIR, | |
optimizer, | |
parallel, | |
@@ -224,7 +205,6 @@ object StandardLinker { | |
* | |
* - `semantics`: [[org.scalajs.core.tools.sem.Semantics.Defaults Semantics.Defaults]] | |
* - `moduleKind`: [[ModuleKind.NoModule]] | |
- * - `bypassLinkingErrors`: `false` (deprecated) | |
* - `checkIR`: `false` | |
* - `optimizer`: `true` | |
* - `parallel`: `true` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment